diff --git a/src/com/dougkeen/bart/activities/ViewDeparturesActivity.java b/src/com/dougkeen/bart/activities/ViewDeparturesActivity.java index 105c22f..9203b3d 100644 --- a/src/com/dougkeen/bart/activities/ViewDeparturesActivity.java +++ b/src/com/dougkeen/bart/activities/ViewDeparturesActivity.java @@ -39,7 +39,7 @@ import com.actionbarsherlock.view.MenuInflater; import com.actionbarsherlock.view.MenuItem; import com.dougkeen.bart.BartRunnerApplication; import com.dougkeen.bart.R; -import com.dougkeen.bart.controls.SwipeDismissTouchListener; +import com.dougkeen.bart.controls.SwipeHelper; import com.dougkeen.bart.controls.Ticker; import com.dougkeen.bart.controls.YourTrainLayout; import com.dougkeen.bart.data.DepartureArrayAdapter; @@ -189,9 +189,8 @@ public class ViewDeparturesActivity extends SActivity implements mYourTrainSection = (YourTrainLayout) findViewById(R.id.yourTrainSection); mYourTrainSection.setOnClickListener(mYourTrainSectionClickListener); - mYourTrainSection.setOnTouchListener(new SwipeDismissTouchListener( - mYourTrainSection, null, - new SwipeDismissTouchListener.OnDismissCallback() { + mSwipeHelper = new SwipeHelper(mYourTrainSection, null, + new SwipeHelper.OnDismissCallback() { @Override public void onDismiss(View view, Object token) { dismissYourTrainSelection(); @@ -201,7 +200,8 @@ public class ViewDeparturesActivity extends SActivity implements mActionMode.finish(); } } - })); + }); + mYourTrainSection.setOnTouchListener(mSwipeHelper); refreshBoardedDeparture(); @@ -363,6 +363,8 @@ public class ViewDeparturesActivity extends SActivity implements private YourTrainLayout mYourTrainSection; + private SwipeHelper mSwipeHelper; + protected DepartureArrayAdapter getListAdapter() { return mDeparturesAdapter; } @@ -480,7 +482,7 @@ public class ViewDeparturesActivity extends SActivity implements mYourTrainSection.updateFromDeparture(boardedDeparture); if (currentVisibility != View.VISIBLE) { - showYourTrainSection(mYourTrainSection); + showYourTrainSection(); } if (mActionMode == null) { @@ -678,7 +680,7 @@ public class ViewDeparturesActivity extends SActivity implements startService(intent); return true; } else if (itemId == R.id.delete) { - dismissYourTrainSelection(); + mSwipeHelper.dismissWithAnimation(true); mode.finish(); return true; } @@ -770,11 +772,37 @@ public class ViewDeparturesActivity extends SActivity implements refreshBoardedDeparture(); getListAdapter().notifyDataSetChanged(); + + refreshListSelection(); } } }); } + private void refreshListSelection() { + getListView().clearChoices(); + final Departure targetDeparture; + if (isDepartureActionModeActive() && mSelectedDeparture != null) { + targetDeparture = mSelectedDeparture; + } else { + targetDeparture = ((BartRunnerApplication) getApplication()) + .getBoardedDeparture(); + } + for (int i = getListAdapter().getCount() - 1; i >= 0; i--) { + if (getListAdapter().getItem(i).equals(targetDeparture)) { + final int selectedIndex = i; + getListView().post(new Runnable() { + @Override + public void run() { + getListView().setSelection(selectedIndex); + } + }); + break; + } + } + getListView().requestLayout(); + } + @Override public void onError(final String errorMessage) { runOnUiThread(new Runnable() { @@ -816,11 +844,12 @@ public class ViewDeparturesActivity extends SActivity implements } private void hideYourTrainSection() { - findViewById(R.id.yourTrainSection).setVisibility(View.GONE); + mYourTrainSection.setVisibility(View.GONE); } - private void showYourTrainSection(final YourTrainLayout yourTrainSection) { - yourTrainSection.setVisibility(View.VISIBLE); + private void showYourTrainSection() { + mYourTrainSection.setVisibility(View.VISIBLE); + mSwipeHelper.showWithAnimation(); } private boolean isYourTrainActionModeActive() { diff --git a/src/com/dougkeen/bart/controls/SwipeDismissTouchListener.java b/src/com/dougkeen/bart/controls/SwipeHelper.java similarity index 74% rename from src/com/dougkeen/bart/controls/SwipeDismissTouchListener.java rename to src/com/dougkeen/bart/controls/SwipeHelper.java index c82d113..490d21b 100644 --- a/src/com/dougkeen/bart/controls/SwipeDismissTouchListener.java +++ b/src/com/dougkeen/bart/controls/SwipeHelper.java @@ -1,4 +1,5 @@ /* + * Copyright 2012 Doug Keen * Copyright 2012 Roman Nurik * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,23 +19,27 @@ package com.dougkeen.bart.controls; +import static com.nineoldandroids.view.ViewHelper.setAlpha; +import static com.nineoldandroids.view.ViewHelper.setTranslationX; +import static com.nineoldandroids.view.ViewPropertyAnimator.animate; +import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; +import android.view.View.MeasureSpec; import android.view.ViewConfiguration; import android.view.ViewGroup; + +import com.dougkeen.bart.model.Constants; import com.nineoldandroids.animation.Animator; import com.nineoldandroids.animation.AnimatorListenerAdapter; import com.nineoldandroids.animation.ValueAnimator; -import static com.nineoldandroids.view.ViewHelper.setAlpha; -import static com.nineoldandroids.view.ViewHelper.setTranslationX; -import static com.nineoldandroids.view.ViewPropertyAnimator.animate; - /** - * A {@link android.view.View.OnTouchListener} that makes any {@link View} - * dismissable when the user swipes (drags her finger) horizontally across the - * view. + * A utility class for animating the dismissal of a view (with 'onDismiss' + * callback). Also, a {@link android.view.View.OnTouchListener} that makes any + * {@link View} dismissable when the user swipes (drags her finger) horizontally + * across the view. * *

* For {@link android.widget.ListView} list items that don't manage their own touch events @@ -49,10 +54,10 @@ import static com.nineoldandroids.view.ViewPropertyAnimator.animate; *

* *
- * view.setOnTouchListener(new SwipeDismissTouchListener(view, null, // Optional
- * 																	// token/cookie
- * 																	// object
- * 		new SwipeDismissTouchListener.OnDismissCallback() {
+ * view.setOnTouchListener(new SwipeDismisser(view, null, // Optional
+ * 														// token/cookie
+ * 														// object
+ * 		new SwipeDismisser.OnDismissCallback() {
  * 			public void onDismiss(View view, Object token) {
  * 				parent.removeView(view);
  * 			}
@@ -61,7 +66,7 @@ import static com.nineoldandroids.view.ViewPropertyAnimator.animate;
  * 
  * @see SwipeDismissListViewTouchListener
  */
-public class SwipeDismissTouchListener implements View.OnTouchListener {
+public class SwipeHelper implements View.OnTouchListener {
 	// Cached ViewConfiguration and system-wide constant values
 	private int mSlop;
 	private int mMinFlingVelocity;
@@ -81,9 +86,8 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 	private float mTranslationX;
 
 	/**
-	 * The callback interface used by {@link SwipeDismissTouchListener} to
-	 * inform its client about a successful dismissal of the view for which it
-	 * was created.
+	 * The callback interface used by {@link SwipeHelper} to inform its
+	 * client about a successful dismissal of the view for which it was created.
 	 */
 	public interface OnDismissCallback {
 		/**
@@ -110,8 +114,7 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 	 *            The callback to trigger when the user has indicated that she
 	 *            would like to dismiss this view.
 	 */
-	public SwipeDismissTouchListener(View view, Object token,
-			OnDismissCallback callback) {
+	public SwipeHelper(View view, Object token, OnDismissCallback callback) {
 		ViewConfiguration vc = ViewConfiguration.get(view.getContext());
 		mSlop = vc.getScaledTouchSlop();
 		mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
@@ -125,6 +128,7 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 
 	@Override
 	public boolean onTouch(View view, MotionEvent motionEvent) {
+		Log.v(Constants.TAG, "onTouch()");
 		// offset because the view is translated during swipe
 		motionEvent.offsetLocation(mTranslationX, 0);
 
@@ -164,15 +168,7 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 			}
 			if (dismiss) {
 				// dismiss
-				animate(mView)
-						.translationX(dismissRight ? mViewWidth : -mViewWidth)
-						.alpha(0).setDuration(mAnimationTime)
-						.setListener(new AnimatorListenerAdapter() {
-							@Override
-							public void onAnimationEnd(Animator animation) {
-								performDismiss();
-							}
-						});
+				dismissWithAnimation(dismissRight);
 			} else {
 				// cancel
 				animate(mView).translationX(0).alpha(1)
@@ -222,6 +218,17 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 		return false;
 	}
 
+	public void dismissWithAnimation(boolean dismissRight) {
+		animate(mView).translationX(dismissRight ? mViewWidth : -mViewWidth)
+				.alpha(0).setDuration(mAnimationTime)
+				.setListener(new AnimatorListenerAdapter() {
+					@Override
+					public void onAnimationEnd(Animator animation) {
+						performDismiss();
+					}
+				});
+	}
+
 	private void performDismiss() {
 		// Animate the dismissed view to zero-height and then fire the dismiss
 		// callback.
@@ -257,4 +264,46 @@ public class SwipeDismissTouchListener implements View.OnTouchListener {
 
 		animator.start();
 	}
+
+	public void showWithAnimation() {
+		final int measureSpec = MeasureSpec.makeMeasureSpec(
+				ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.EXACTLY);
+		mView.measure(measureSpec, measureSpec);
+		mViewWidth = mView.getMeasuredWidth();
+		final int viewHeight = mView.getMeasuredHeight();
+		setAlpha(mView, 0f);
+
+		final ViewGroup.LayoutParams lp = mView.getLayoutParams();
+		lp.width = mViewWidth;
+
+		setTranslationX(mView, mViewWidth);
+
+		// Grow space
+		ValueAnimator animator = ValueAnimator.ofInt(1, viewHeight)
+				.setDuration(mAnimationTime);
+
+		animator.addListener(new AnimatorListenerAdapter() {
+			@Override
+			public void onAnimationEnd(Animator animation) {
+				// Reset view presentation
+				// mView.requestLayout();
+
+				// Swipe view into space that opened up
+				animate(mView).translationX(0).alpha(1)
+						.setDuration(mAnimationTime)
+						.setListener(new AnimatorListenerAdapter() {
+						});
+			}
+		});
+
+		animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+			@Override
+			public void onAnimationUpdate(ValueAnimator valueAnimator) {
+				lp.height = (Integer) valueAnimator.getAnimatedValue();
+				mView.setLayoutParams(lp);
+			}
+		});
+
+		animator.start();
+	}
 }
\ No newline at end of file