|
|
@ -18,6 +18,7 @@ |
|
|
|
package org.floens.chan.controller.ui; |
|
|
|
package org.floens.chan.controller.ui; |
|
|
|
|
|
|
|
|
|
|
|
import android.content.Context; |
|
|
|
import android.content.Context; |
|
|
|
|
|
|
|
import android.content.res.Configuration; |
|
|
|
import android.graphics.Canvas; |
|
|
|
import android.graphics.Canvas; |
|
|
|
import android.graphics.Color; |
|
|
|
import android.graphics.Color; |
|
|
|
import android.graphics.Paint; |
|
|
|
import android.graphics.Paint; |
|
|
@ -32,30 +33,57 @@ import android.widget.Scroller; |
|
|
|
|
|
|
|
|
|
|
|
import org.floens.chan.controller.Controller; |
|
|
|
import org.floens.chan.controller.Controller; |
|
|
|
import org.floens.chan.controller.NavigationController; |
|
|
|
import org.floens.chan.controller.NavigationController; |
|
|
|
|
|
|
|
import org.floens.chan.utils.Logger; |
|
|
|
import org.floens.chan.utils.Time; |
|
|
|
import org.floens.chan.utils.Time; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import static org.floens.chan.utils.AndroidUtils.dp; |
|
|
|
|
|
|
|
|
|
|
|
public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
|
|
|
|
// The shadow starts at this alpha and goes up to 1f
|
|
|
|
|
|
|
|
public static final float SHADOW_MIN_ALPHA = 0.5f; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private NavigationController navigationController; |
|
|
|
private NavigationController navigationController; |
|
|
|
|
|
|
|
|
|
|
|
private int slopPixels; |
|
|
|
private int slopPixels; |
|
|
|
|
|
|
|
private int minimalMovedPixels; |
|
|
|
private int flingPixels; |
|
|
|
private int flingPixels; |
|
|
|
private int maxFlingPixels; |
|
|
|
private int maxFlingPixels; |
|
|
|
|
|
|
|
|
|
|
|
private boolean swipeEnabled = true; |
|
|
|
private boolean swipeEnabled = true; |
|
|
|
|
|
|
|
|
|
|
|
private MotionEvent downEvent; |
|
|
|
// The event used in onInterceptTouchEvent to track the initial down event
|
|
|
|
private boolean dontStartSwiping = false; |
|
|
|
private MotionEvent interceptedEvent; |
|
|
|
private MotionEvent swipeStartEvent; |
|
|
|
|
|
|
|
|
|
|
|
// The tracking is blocked when the user has moved too much in the y direction
|
|
|
|
|
|
|
|
private boolean blockTracking = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Is the top controller being tracked and moved
|
|
|
|
|
|
|
|
private boolean tracking = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The controller being tracked, corresponds with tracking
|
|
|
|
|
|
|
|
private Controller trackingController; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The controller behind the tracking controller
|
|
|
|
|
|
|
|
private Controller behindTrackingController; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The position of the touch after tracking has started, used to calculate the total offset from
|
|
|
|
|
|
|
|
private int trackStartPosition; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Tracks the motion when tracking
|
|
|
|
private VelocityTracker velocityTracker; |
|
|
|
private VelocityTracker velocityTracker; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Used to fling and scroll the tracking view
|
|
|
|
private Scroller scroller; |
|
|
|
private Scroller scroller; |
|
|
|
private boolean popAfterSwipe = false; |
|
|
|
|
|
|
|
|
|
|
|
// Indicate if the controller should be popped after the animation ends
|
|
|
|
|
|
|
|
private boolean finishTransitionAfterAnimation = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Paint, draw rect and position for drawing the shadow
|
|
|
|
|
|
|
|
// The shadow is only drawn when tracking is true
|
|
|
|
private Paint shadowPaint; |
|
|
|
private Paint shadowPaint; |
|
|
|
private Rect shadowRect = new Rect(); |
|
|
|
private Rect shadowRect = new Rect(); |
|
|
|
private boolean drawShadow; |
|
|
|
private int shadowPosition; |
|
|
|
private int swipePosition; |
|
|
|
|
|
|
|
private boolean swiping = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Controller swipingController; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public NavigationControllerContainerLayout(Context context) { |
|
|
|
public NavigationControllerContainerLayout(Context context) { |
|
|
|
super(context); |
|
|
|
super(context); |
|
|
@ -74,7 +102,8 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
|
|
|
|
|
|
|
|
private void init() { |
|
|
|
private void init() { |
|
|
|
ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext()); |
|
|
|
ViewConfiguration viewConfiguration = ViewConfiguration.get(getContext()); |
|
|
|
slopPixels = (int) (viewConfiguration.getScaledTouchSlop() * 0.5f); |
|
|
|
slopPixels = viewConfiguration.getScaledTouchSlop(); |
|
|
|
|
|
|
|
minimalMovedPixels = dp(3); |
|
|
|
flingPixels = viewConfiguration.getScaledMinimumFlingVelocity(); |
|
|
|
flingPixels = viewConfiguration.getScaledMinimumFlingVelocity(); |
|
|
|
maxFlingPixels = viewConfiguration.getScaledMaximumFlingVelocity(); |
|
|
|
maxFlingPixels = viewConfiguration.getScaledMaximumFlingVelocity(); |
|
|
|
|
|
|
|
|
|
|
@ -93,51 +122,34 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean onInterceptTouchEvent(MotionEvent event) { |
|
|
|
public boolean onInterceptTouchEvent(MotionEvent event) { |
|
|
|
if (!swipeEnabled || swiping) { |
|
|
|
if (!swipeEnabled || tracking || navigationController.isBlockingInput() || !navigationController.getTop().navigationItem.swipeable || getBelowTop() == null) { |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int actionMasked = event.getActionMasked(); |
|
|
|
int actionMasked = event.getActionMasked(); |
|
|
|
|
|
|
|
|
|
|
|
if (actionMasked != MotionEvent.ACTION_DOWN && downEvent == null) { |
|
|
|
if (actionMasked != MotionEvent.ACTION_DOWN && interceptedEvent == null) { |
|
|
|
// Action down wasn't called here, ignore
|
|
|
|
// Action down wasn't called here, ignore
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!navigationController.getTop().navigationItem.swipeable) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (getBelowTop() == null) { |
|
|
|
|
|
|
|
// Cannot swipe now
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (actionMasked) { |
|
|
|
switch (actionMasked) { |
|
|
|
case MotionEvent.ACTION_DOWN: |
|
|
|
case MotionEvent.ACTION_DOWN: |
|
|
|
// Logger.test("onInterceptTouchEvent down");
|
|
|
|
// Logger.test("onInterceptTouchEvent down");
|
|
|
|
downEvent = MotionEvent.obtain(event); |
|
|
|
interceptedEvent = MotionEvent.obtain(event); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case MotionEvent.ACTION_MOVE: { |
|
|
|
case MotionEvent.ACTION_MOVE: { |
|
|
|
// Logger.test("onInterceptTouchEvent move");
|
|
|
|
// Logger.test("onInterceptTouchEvent move");
|
|
|
|
float x = (event.getX() - downEvent.getX()); |
|
|
|
float x = (event.getX() - interceptedEvent.getX()); |
|
|
|
float y = (event.getY() - downEvent.getY()); |
|
|
|
float y = (event.getY() - interceptedEvent.getY()); |
|
|
|
|
|
|
|
|
|
|
|
if (Math.abs(y) >= slopPixels) { |
|
|
|
if (Math.abs(y) >= slopPixels) { |
|
|
|
// Logger.test("dontStartSwiping = true");
|
|
|
|
// Logger.test("blockTracking = true");
|
|
|
|
dontStartSwiping = true; |
|
|
|
blockTracking = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!dontStartSwiping && Math.abs(x) > Math.abs(y) && x >= slopPixels && !navigationController.isBlockingInput()) { |
|
|
|
if (!blockTracking && x >= minimalMovedPixels && Math.abs(x) > Math.abs(y)) { |
|
|
|
// Logger.test("Start tracking swipe");
|
|
|
|
startTracking(event); |
|
|
|
downEvent.recycle(); |
|
|
|
|
|
|
|
downEvent = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
swipeStartEvent = MotionEvent.obtain(event); |
|
|
|
|
|
|
|
velocityTracker = VelocityTracker.obtain(); |
|
|
|
|
|
|
|
velocityTracker.addMovement(event); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
swiping = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
@ -146,9 +158,9 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
case MotionEvent.ACTION_CANCEL: |
|
|
|
case MotionEvent.ACTION_CANCEL: |
|
|
|
case MotionEvent.ACTION_UP: { |
|
|
|
case MotionEvent.ACTION_UP: { |
|
|
|
// Logger.test("onInterceptTouchEvent cancel/up");
|
|
|
|
// Logger.test("onInterceptTouchEvent cancel/up");
|
|
|
|
downEvent.recycle(); |
|
|
|
interceptedEvent.recycle(); |
|
|
|
downEvent = null; |
|
|
|
interceptedEvent = null; |
|
|
|
dontStartSwiping = false; |
|
|
|
blockTracking = false; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -159,41 +171,34 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { |
|
|
|
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { |
|
|
|
if (disallowIntercept) { |
|
|
|
if (disallowIntercept) { |
|
|
|
if (downEvent != null) { |
|
|
|
if (interceptedEvent != null) { |
|
|
|
downEvent.recycle(); |
|
|
|
interceptedEvent.recycle(); |
|
|
|
downEvent = null; |
|
|
|
interceptedEvent = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
blockTracking = false; |
|
|
|
|
|
|
|
if (tracking) { |
|
|
|
|
|
|
|
endTracking(false); |
|
|
|
} |
|
|
|
} |
|
|
|
dontStartSwiping = false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
super.requestDisallowInterceptTouchEvent(disallowIntercept); |
|
|
|
super.requestDisallowInterceptTouchEvent(disallowIntercept); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public boolean onTouchEvent(MotionEvent event) { |
|
|
|
protected void onConfigurationChanged(Configuration newConfig) { |
|
|
|
// This touch wasn't initiated with onInterceptTouchEvent
|
|
|
|
super.onConfigurationChanged(newConfig); |
|
|
|
if (swipeStartEvent == null) { |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (swipingController == null) { |
|
|
|
|
|
|
|
// Start of swipe
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Logger.test("Start of swipe");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
swipingController = navigationController.getTop(); |
|
|
|
// endTracking();
|
|
|
|
drawShadow = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
long start = Time.startTiming(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Controller below = getBelowTop(); |
|
|
|
|
|
|
|
navigationController.beginSwipeTransition(swipingController, below); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Time.endTiming("attach", start); |
|
|
|
@Override |
|
|
|
|
|
|
|
public boolean onTouchEvent(MotionEvent event) { |
|
|
|
|
|
|
|
if (!tracking) { |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float translationX = Math.max(0, event.getX() - swipeStartEvent.getX()); |
|
|
|
int translationX = Math.max(0, ((int) event.getX()) - trackStartPosition); |
|
|
|
setTopControllerTranslation((int) translationX); |
|
|
|
setTopControllerTranslation(translationX); |
|
|
|
|
|
|
|
|
|
|
|
velocityTracker.addMovement(event); |
|
|
|
velocityTracker.addMovement(event); |
|
|
|
|
|
|
|
|
|
|
@ -206,37 +211,42 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
|
|
|
|
|
|
|
|
velocityTracker.addMovement(event); |
|
|
|
velocityTracker.addMovement(event); |
|
|
|
velocityTracker.computeCurrentVelocity(1000); |
|
|
|
velocityTracker.computeCurrentVelocity(1000); |
|
|
|
float velocity = velocityTracker.getXVelocity(); |
|
|
|
int velocity = (int) velocityTracker.getXVelocity(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (translationX > 0) { |
|
|
|
|
|
|
|
boolean doFlingAway = false; |
|
|
|
|
|
|
|
|
|
|
|
if (translationX > 0f) { |
|
|
|
Logger.test("velocity = %d", velocity); |
|
|
|
boolean isFling = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (velocity > 0f && Math.abs(velocity) > flingPixels && Math.abs(velocity) < maxFlingPixels) { |
|
|
|
if ((velocity > 0 && Math.abs(velocity) > 2500 && Math.abs(velocity) < maxFlingPixels) || translationX >= getWidth() * 3 / 4) { |
|
|
|
scroller.fling((int) translationX, 0, (int) velocity, 0, 0, Integer.MAX_VALUE, 0, 0); |
|
|
|
// int left = getWidth() - translationX;
|
|
|
|
|
|
|
|
// int flingVelocity = Math.max(velocity, 0);
|
|
|
|
|
|
|
|
|
|
|
|
if (scroller.getFinalX() >= getWidth()) { |
|
|
|
scroller.fling(translationX, 0, velocity, 0, 0, Integer.MAX_VALUE, 0, 0); |
|
|
|
isFling = true; |
|
|
|
Logger.test("finalX = %d getWidth = %d", scroller.getFinalX(), getWidth()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Make sure the animation always goes past the end
|
|
|
|
|
|
|
|
if (scroller.getFinalX() < getWidth()) { |
|
|
|
|
|
|
|
scroller.startScroll(translationX, 0, getWidth(), 0, 2000); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
doFlingAway = true; |
|
|
|
|
|
|
|
Logger.test("Flinging away with velocity = %d", velocity); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (isFling) { |
|
|
|
if (doFlingAway) { |
|
|
|
// Logger.test("Flinging with velocity = " + velocity);
|
|
|
|
startFlingAnimation(true); |
|
|
|
popAfterSwipe = true; |
|
|
|
|
|
|
|
ViewCompat.postOnAnimation(this, flingRunnable); |
|
|
|
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// Logger.test("Snapping back!");
|
|
|
|
Logger.test("Snapping back"); |
|
|
|
scroller.forceFinished(true); |
|
|
|
scroller.forceFinished(true); |
|
|
|
scroller.startScroll((int) translationX, 0, -((int) translationX), 0, 300); |
|
|
|
scroller.startScroll(translationX, 0, -translationX, 0, 250); |
|
|
|
popAfterSwipe = false; |
|
|
|
startFlingAnimation(false); |
|
|
|
ViewCompat.postOnAnimation(this, flingRunnable); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
finishSwipe(); |
|
|
|
// User swiped back to the left
|
|
|
|
|
|
|
|
endTracking(false); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
swipeStartEvent.recycle(); |
|
|
|
|
|
|
|
swipeStartEvent = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
velocityTracker.recycle(); |
|
|
|
velocityTracker.recycle(); |
|
|
|
velocityTracker = null; |
|
|
|
velocityTracker = null; |
|
|
|
|
|
|
|
|
|
|
@ -251,26 +261,64 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
protected void dispatchDraw(Canvas canvas) { |
|
|
|
protected void dispatchDraw(Canvas canvas) { |
|
|
|
super.dispatchDraw(canvas); |
|
|
|
super.dispatchDraw(canvas); |
|
|
|
|
|
|
|
|
|
|
|
if (drawShadow) { |
|
|
|
if (tracking) { |
|
|
|
float alpha = Math.min(1f, Math.max(0f, 0.5f - (swipePosition / (float) getWidth()) * 0.5f)); |
|
|
|
float alpha = Math.min(1f, Math.max(0f, SHADOW_MIN_ALPHA - (shadowPosition / (float) getWidth()) * SHADOW_MIN_ALPHA)); |
|
|
|
shadowPaint.setColor(Color.argb((int) (alpha * 255f), 0, 0, 0)); |
|
|
|
shadowPaint.setColor(Color.argb((int) (alpha * 255f), 0, 0, 0)); |
|
|
|
shadowRect.set(0, 0, swipePosition, getHeight()); |
|
|
|
shadowRect.set(0, 0, shadowPosition, getHeight()); |
|
|
|
canvas.drawRect(shadowRect, shadowPaint); |
|
|
|
canvas.drawRect(shadowRect, shadowPaint); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void finishSwipe() { |
|
|
|
private void startTracking(MotionEvent startEvent) { |
|
|
|
Controller below = getBelowTop(); |
|
|
|
if (tracking) { |
|
|
|
|
|
|
|
throw new IllegalStateException("startTracking called but already tracking"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tracking = true; |
|
|
|
|
|
|
|
trackingController = navigationController.getTop(); |
|
|
|
|
|
|
|
behindTrackingController = getBelowTop(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
interceptedEvent.recycle(); |
|
|
|
|
|
|
|
interceptedEvent = null; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
trackStartPosition = (int) startEvent.getX(); |
|
|
|
|
|
|
|
velocityTracker = VelocityTracker.obtain(); |
|
|
|
|
|
|
|
velocityTracker.addMovement(startEvent); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long start = Time.startTiming(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
navigationController.beginSwipeTransition(trackingController, behindTrackingController); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Time.endTiming("attach", start); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Logger.test("Start tracking " + trackingController.getClass().getSimpleName()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void endTracking(boolean finishTransition) { |
|
|
|
|
|
|
|
Logger.test("endTracking finishTransition = " + finishTransition); |
|
|
|
|
|
|
|
|
|
|
|
navigationController.endSwipeTransition(swipingController, below, popAfterSwipe); |
|
|
|
if (!tracking) { |
|
|
|
swipingController = null; |
|
|
|
throw new IllegalStateException("endTracking called but was not tracking"); |
|
|
|
drawShadow = false; |
|
|
|
} |
|
|
|
swiping = false; |
|
|
|
|
|
|
|
|
|
|
|
navigationController.endSwipeTransition(trackingController, behindTrackingController, finishTransition); |
|
|
|
|
|
|
|
tracking = false; |
|
|
|
|
|
|
|
trackingController = null; |
|
|
|
|
|
|
|
behindTrackingController = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void startFlingAnimation(boolean finishTransitionAfterAnimation) { |
|
|
|
|
|
|
|
this.finishTransitionAfterAnimation = finishTransitionAfterAnimation; |
|
|
|
|
|
|
|
ViewCompat.postOnAnimation(this, flingRunnable); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Runnable flingRunnable = new Runnable() { |
|
|
|
private Runnable flingRunnable = new Runnable() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
|
|
|
|
if (!tracking) { |
|
|
|
|
|
|
|
throw new IllegalStateException("fling animation running while not tracking"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
boolean finished = false; |
|
|
|
boolean finished = false; |
|
|
|
|
|
|
|
|
|
|
|
if (scroller.computeScrollOffset()) { |
|
|
|
if (scroller.computeScrollOffset()) { |
|
|
@ -289,15 +337,15 @@ public class NavigationControllerContainerLayout extends FrameLayout { |
|
|
|
if (!finished) { |
|
|
|
if (!finished) { |
|
|
|
ViewCompat.postOnAnimation(NavigationControllerContainerLayout.this, flingRunnable); |
|
|
|
ViewCompat.postOnAnimation(NavigationControllerContainerLayout.this, flingRunnable); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
finishSwipe(); |
|
|
|
endTracking(finishTransitionAfterAnimation); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
private void setTopControllerTranslation(int translationX) { |
|
|
|
private void setTopControllerTranslation(int translationX) { |
|
|
|
swipePosition = translationX; |
|
|
|
shadowPosition = translationX; |
|
|
|
swipingController.view.setTranslationX(swipePosition); |
|
|
|
trackingController.view.setTranslationX(translationX); |
|
|
|
navigationController.swipeTransitionProgress(swipePosition / (float) getWidth()); |
|
|
|
navigationController.swipeTransitionProgress(translationX / (float) getWidth()); |
|
|
|
invalidate(); |
|
|
|
invalidate(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|