diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java index 152f03fb4..b891d7537 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIActivity.java @@ -28,10 +28,12 @@ import com.qmuiteam.qmui.util.QMUIDisplayHelper; import com.qmuiteam.qmui.util.QMUIStatusBarHelper; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_BOTTOM_TO_TOP; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_LEFT_TO_RIGHT; +import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_NONE; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_RIGHT_TO_LEFT; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_TOP_TO_BOTTOM; import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_BOTTOM; @@ -105,16 +107,15 @@ public void onScrollOverThreshold() { } }; private SwipeBackLayout.Callback mSwipeCallback = new SwipeBackLayout.Callback() { - @Override - public boolean canSwipeBack(SwipeBackLayout layout, int dragDirection, int moveEdge) { - return QMUISwipeBackActivityManager.getInstance().canSwipeBack() && - canDragBack(layout.getContext(), dragDirection, moveEdge); - } @Override - public boolean shouldBeginDrag(SwipeBackLayout swipeBackLayout, - float downX, float downY, int direction) { - return QMUIActivity.this.shouldBeginDrag(swipeBackLayout, downX, downY, direction); + public int getDragDirection(SwipeBackLayout swipeBackLayout, + SwipeBackLayout.ViewMoveAction moveAction, + float downX, float downY, float dx, float dy, float touchSlop) { + if(!QMUISwipeBackActivityManager.getInstance().canSwipeBack()){ + return SwipeBackLayout.DRAG_DIRECTION_NONE; + } + return QMUIActivity.this.getDragDirection(swipeBackLayout,moveAction,downX, downY, dx, dy, touchSlop); } }; @@ -135,8 +136,7 @@ public void setContentView(View view) { @Override public void setContentView(int layoutResID) { - SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(this, - layoutResID, dragBackDirection(), dragViewMoveAction(), mSwipeCallback); + SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(this, layoutResID, dragViewMoveAction(), mSwipeCallback); if (translucentFull()) { swipeBackLayout.getContentView().setFitsSystemWindows(false); } else { @@ -157,8 +157,7 @@ private View newSwipeBackLayout(View view) { } else { view.setFitsSystemWindows(true); } - final SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap( - view, dragBackDirection(), dragViewMoveAction(), mSwipeCallback); + final SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(view, dragViewMoveAction(), mSwipeCallback); mListenerRemover = swipeBackLayout.addSwipeListener(mSwipeListener); return swipeBackLayout; } @@ -197,7 +196,7 @@ public boolean isInSwipeBack() { * disable or enable drag back * * @return if true open dragBack, otherwise close dragBack - * @deprecated Use {@link #canDragBack(Context, int, int)} + * @deprecated Use {@link #getDragDirection(SwipeBackLayout, SwipeBackLayout.ViewMoveAction, float, float, float, float, float)} */ @Deprecated protected boolean canDragBack() { @@ -205,6 +204,13 @@ protected boolean canDragBack() { } + /** + * disable or enable drag back + * + * @return if true open dragBack, otherwise close dragBack + * @deprecated Use {@link #getDragDirection(SwipeBackLayout, SwipeBackLayout.ViewMoveAction, float, float, float, float, float)} + */ + @Deprecated protected boolean canDragBack(Context context, int dragDirection, int moveEdge) { return canDragBack(); } @@ -222,19 +228,33 @@ protected int backViewInitOffset(Context context, int dragDirection, int moveEdg return backViewInitOffset(); } - protected boolean shouldBeginDrag(SwipeBackLayout swipeBackLayout, - float downX, float downY, int dragDirection){ + protected int getDragDirection(@NonNull SwipeBackLayout swipeBackLayout, + @NonNull SwipeBackLayout.ViewMoveAction viewMoveAction, + float downX, float downY, float dx, float dy, float slopTouch){ + int targetDirection = dragBackDirection(); + if(!canDragBack(swipeBackLayout.getContext(), targetDirection, viewMoveAction.getEdge(targetDirection))){ + return DRAG_DIRECTION_NONE; + } int edgeSize = QMUIDisplayHelper.dp2px(swipeBackLayout.getContext(), 20); - if(dragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT){ - return downX < edgeSize; - }else if(dragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT){ - return downX > swipeBackLayout.getWidth() - edgeSize; - }else if(dragDirection == DRAG_DIRECTION_TOP_TO_BOTTOM){ - return downY < edgeSize; - }else if(dragDirection == DRAG_DIRECTION_BOTTOM_TO_TOP){ - return downY > swipeBackLayout.getHeight() - edgeSize; + if (targetDirection == DRAG_DIRECTION_LEFT_TO_RIGHT) { + if(downX < edgeSize && dx >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { + if(downX > swipeBackLayout.getWidth() - edgeSize && -dx >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_TOP_TO_BOTTOM) { + if(downY < edgeSize && dy >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_BOTTOM_TO_TOP) { + if(downY > swipeBackLayout.getHeight() - edgeSize && -dy >= slopTouch){ + return targetDirection; + } } - return true; + + return DRAG_DIRECTION_NONE; } /** diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java index 801507af2..39be1f2aa 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/QMUIFragment.java @@ -74,6 +74,7 @@ import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_BOTTOM_TO_TOP; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_LEFT_TO_RIGHT; +import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_NONE; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_RIGHT_TO_LEFT; import static com.qmuiteam.qmui.arch.SwipeBackLayout.DRAG_DIRECTION_TOP_TO_BOTTOM; import static com.qmuiteam.qmui.arch.SwipeBackLayout.EDGE_BOTTOM; @@ -469,9 +470,11 @@ private int startFragment(QMUIFragment fragment, QMUIFragmentContainerProvider p } /** - * @deprecated use {@link #notifyEffect} for a replacement + * * @param resultCode * @param data + * + * @deprecated use {@link #notifyEffect} for a replacement */ @Deprecated public void setFragmentResult(int resultCode, Intent data) { @@ -508,59 +511,55 @@ private SwipeBackLayout newSwipeBackLayout() { } else { rootView.setFitsSystemWindows(true); } - final SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(rootView, dragBackDirection(), + final SwipeBackLayout swipeBackLayout = SwipeBackLayout.wrap(rootView, dragViewMoveAction(), new SwipeBackLayout.Callback() { @Override - public boolean canSwipeBack(SwipeBackLayout layout, int dragDirection, int moveEdge) { + public int getDragDirection(SwipeBackLayout swipeBackLayout, SwipeBackLayout.ViewMoveAction viewMoveAction, float downX, float downY, float dx, float dy, float touchSlop) { // 1. can not swipe back if in animation if (mEnterAnimationStatus != ANIMATION_ENTER_STATUS_END) { - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } // 2. can not swipe back if it is not managed by FragmentContainer QMUIFragmentContainerProvider provider = findFragmentContainerProvider(); if(provider == null){ - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } FragmentManager fragmentManager = provider.getContainerFragmentManager(); if(fragmentManager == null || fragmentManager != getParentFragmentManager()){ - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } // 3. need be handled by inner FragmentContainer if(fragmentManager.getPrimaryNavigationFragment() != null){ - return false; - } - - if (!canDragBack(layout.getContext(), dragDirection, moveEdge)) { - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } + // 4. can not swipe back if the view is null View view = getView(); if (view == null) { - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } - // if the Fragment is in ViewPager, then stop drag back + // 5. can not swipe back if if the Fragment is in ViewPager ViewParent parent = view.getParent(); while (parent != null) { if (parent instanceof ViewPager || parent instanceof ViewPager2) { - return false; + return SwipeBackLayout.DRAG_DIRECTION_NONE; } parent = parent.getParent(); } - if (fragmentManager.getBackStackEntryCount() <= 1) { - return QMUISwipeBackActivityManager.getInstance().canSwipeBack(); + // 6. can not swipe back if the backStack entry count is less than 2 + if (fragmentManager.getBackStackEntryCount() <= 1 && + !QMUISwipeBackActivityManager.getInstance().canSwipeBack()) { + return SwipeBackLayout.DRAG_DIRECTION_NONE; } - return true; - } - @Override - public boolean shouldBeginDrag(SwipeBackLayout swipeBackLayout, float downX, float downY, int dragDirection) { - return QMUIFragment.this.shouldBeginDrag(swipeBackLayout, downX, downY, dragDirection); + return QMUIFragment.this.getDragDirection( + swipeBackLayout, viewMoveAction, downX, downY, dx, dy, touchSlop); } }); mListenerRemover = swipeBackLayout.addSwipeListener(mSwipeListener); @@ -1112,7 +1111,10 @@ protected void onViewCreated(@NonNull View rootView) { * @param requestCode request code * @param resultCode result code * @param data extra data + * + * @deprecated use {@link #registerEffect} for a replacement */ + @Deprecated protected void onFragmentResult(int requestCode, int resultCode, Intent data) { } @@ -1121,7 +1123,7 @@ protected void onFragmentResult(int requestCode, int resultCode, Intent data) { * disable or enable drag back * * @return if true open dragBack, otherwise close dragBack - * @deprecated Use {@link #canDragBack(Context, int, int)} + * @deprecated Use {@link #getDragDirection(SwipeBackLayout, SwipeBackLayout.ViewMoveAction, float, float, float, float, float)} */ @Deprecated protected boolean canDragBack() { @@ -1129,6 +1131,16 @@ protected boolean canDragBack() { } + /** + * disable or enable drag back + * @param context context + * @param dragDirection gesture direction + * @param moveEdge view move edge + * @return if true open dragBack, otherwise close dragBack + * + * @deprecated Use {@link #getDragDirection(SwipeBackLayout, SwipeBackLayout.ViewMoveAction, float, float, float, float, float)} + */ + @Deprecated protected boolean canDragBack(Context context, int dragDirection, int moveEdge) { return canDragBack(); } @@ -1162,6 +1174,12 @@ protected int dragBackEdge() { return EDGE_LEFT; } + /** + * + * @return + * @deprecated Use {@link #getDragDirection(SwipeBackLayout, SwipeBackLayout.ViewMoveAction, float, float, float, float, float)} + */ + @Deprecated protected int dragBackDirection() { int oldEdge = dragBackEdge(); if (oldEdge == EDGE_RIGHT) { @@ -1178,19 +1196,33 @@ protected SwipeBackLayout.ViewMoveAction dragViewMoveAction() { return SwipeBackLayout.MOVE_VIEW_AUTO; } - protected boolean shouldBeginDrag(SwipeBackLayout swipeBackLayout, - float downX, float downY, int dragDirection) { + protected int getDragDirection(@NonNull SwipeBackLayout swipeBackLayout, + @NonNull SwipeBackLayout.ViewMoveAction viewMoveAction, + float downX, float downY, float dx, float dy, float slopTouch){ + int targetDirection = dragBackDirection(); + if(!canDragBack(swipeBackLayout.getContext(), targetDirection, viewMoveAction.getEdge(targetDirection))){ + return DRAG_DIRECTION_NONE; + } int edgeSize = QMUIDisplayHelper.dp2px(swipeBackLayout.getContext(), 20); - if (dragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT) { - return downX < edgeSize; - } else if (dragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { - return downX > swipeBackLayout.getWidth() - edgeSize; - } else if (dragDirection == DRAG_DIRECTION_TOP_TO_BOTTOM) { - return downY < edgeSize; - } else if (dragDirection == DRAG_DIRECTION_BOTTOM_TO_TOP) { - return downY > swipeBackLayout.getHeight() - edgeSize; + if (targetDirection == DRAG_DIRECTION_LEFT_TO_RIGHT) { + if(downX < edgeSize && dx >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { + if(downX > swipeBackLayout.getWidth() - edgeSize && -dx >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_TOP_TO_BOTTOM) { + if(downY < edgeSize && dy >= slopTouch){ + return targetDirection; + } + } else if (targetDirection == DRAG_DIRECTION_BOTTOM_TO_TOP) { + if(downY > swipeBackLayout.getHeight() - edgeSize && -dy >= slopTouch){ + return targetDirection; + } } - return true; + + return DRAG_DIRECTION_NONE; } /** diff --git a/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java b/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java index aeb8d0a9c..3ae706ca8 100644 --- a/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java +++ b/arch/src/main/java/com/qmuiteam/qmui/arch/SwipeBackLayout.java @@ -60,6 +60,7 @@ public class SwipeBackLayout extends QMUIWindowInsetLayout { private static final int MAX_SETTLE_DURATION = 600; // ms + public static final int DRAG_DIRECTION_NONE = 0; public static final int DRAG_DIRECTION_LEFT_TO_RIGHT = 1; public static final int DRAG_DIRECTION_RIGHT_TO_LEFT = 2; public static final int DRAG_DIRECTION_TOP_TO_BOTTOM = 3; @@ -108,10 +109,10 @@ public class SwipeBackLayout extends QMUIWindowInsetLayout { private QMUIViewOffsetHelper mViewOffsetHelper; private ViewMoveAction mViewMoveAction = MOVE_VIEW_AUTO; - private int mDragDirection; + private int mCurrentDragDirection = 0; private boolean mIsScrollOverValid = true; + private boolean mEnableSwipeBack = true; - private boolean mPreventSwipeBackWhenDown = false; public SwipeBackLayout(Context context) { this(context, null); @@ -127,8 +128,6 @@ public SwipeBackLayout(Context context, AttributeSet attrs, int defStyle) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SwipeBackLayout, defStyle, R.style.SwipeBackLayout); - mDragDirection = a.getInt(R.styleable.SwipeBackLayout_drag_direction, DRAG_DIRECTION_LEFT_TO_RIGHT); - int shadowLeft = a.getResourceId(R.styleable.SwipeBackLayout_shadow_left, R.drawable.shadow_left); int shadowRight = a.getResourceId(R.styleable.SwipeBackLayout_shadow_right, @@ -151,6 +150,14 @@ public SwipeBackLayout(Context context, AttributeSet attrs, int defStyle) { mScroller = new OverScroller(context, QUNITIC_INTERPOLATOR); } + public void setEnableSwipeBack(boolean enableSwipeBack) { + mEnableSwipeBack = enableSwipeBack; + } + + public boolean isEnableSwipeBack() { + return mEnableSwipeBack; + } + private final Runnable mSetIdleRunnable = new Runnable() { @Override public void run() { @@ -180,16 +187,6 @@ public void setCallback(Callback callback) { mCallback = callback; } - private boolean canSwipeBack() { - return mContentView != null && (mCallback == null || - mCallback.canSwipeBack( - this, mDragDirection, mViewMoveAction.getEdge(mDragDirection))); - } - - public void setDragDirection(int dragDirection) { - mDragDirection = dragDirection; - } - /** * Set a color to use for the scrim that obscures primary content while a * drawer is open. @@ -315,16 +312,6 @@ public void setShadow(int resId, int edgeFlag) { setShadow(getResources().getDrawable(resId), edgeFlag); } - - private boolean preventSwipeBack(MotionEvent event) { - if (event.getAction() == MotionEvent.ACTION_DOWN) { - mPreventSwipeBackWhenDown = !canSwipeBack(); - return mPreventSwipeBackWhenDown; - } else { - return !canSwipeBack() || mPreventSwipeBackWhenDown; - } - } - void setDragState(int state) { removeCallbacks(mSetIdleRunnable); if (mDragState != state) { @@ -338,33 +325,24 @@ private boolean isTouchInContentView(float x, float y) { && y >= mContentView.getTop() && y < mContentView.getBottom(); } - private boolean shouldStartDrag(float x, float y) { + + private int selectDragDirection(float x, float y) { final float dx = x - mInitialMotionX; final float dy = y - mInitialMotionY; - boolean start = false; - if (mDragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT) { - start = dx >= mTouchSlop; - } else if (mDragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { - start = -dx >= mTouchSlop; - } else if (mDragDirection == DRAG_DIRECTION_TOP_TO_BOTTOM) { - start = dy >= mTouchSlop; - } else if (mDragDirection == DRAG_DIRECTION_BOTTOM_TO_TOP) { - start = -dy >= mTouchSlop; - } - - start = start && (mCallback == null || - mCallback.shouldBeginDrag(this, mInitialMotionX, mInitialMotionY, mDragDirection)); - if (start) { + mCurrentDragDirection = mCallback == null ? DRAG_DIRECTION_NONE : + mCallback.getDragDirection(this, mViewMoveAction, mInitialMotionX, mInitialMotionY, dx, dy, mTouchSlop); + if(mCurrentDragDirection != DRAG_DIRECTION_NONE){ mInitialMotionX = mLastMotionX = x; mInitialMotionY = mLastMotionY = y; onSwipeBackBegin(); + setDragState(STATE_DRAGGING); } - return start; + return mCurrentDragDirection; } private float getTouchMoveDelta(float x, float y) { - if (mDragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT || - mDragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { + if (mCurrentDragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT || + mCurrentDragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT) { return x - mLastMotionX; } else { return y - mLastMotionY; @@ -373,11 +351,12 @@ private float getTouchMoveDelta(float x, float y) { @Override public boolean onInterceptTouchEvent(MotionEvent ev) { - if (preventSwipeBack(ev)) { + if(!mEnableSwipeBack){ + cancel(); return false; } - final int action = ev.getActionMasked(); + final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { cancel(); } @@ -386,6 +365,8 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMovement(ev); + + final float x = ev.getX(); final float y = ev.getY(); switch (action) { @@ -402,20 +383,16 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { case MotionEvent.ACTION_MOVE: { if (mDragState == STATE_IDLE) { - boolean shouldStartDrag = shouldStartDrag(x, y); - if (shouldStartDrag) { - setDragState(STATE_DRAGGING); - } + selectDragDirection(x, y); } else if (mDragState == STATE_DRAGGING) { mViewMoveAction.move(this, mContentView, mViewOffsetHelper, - mDragDirection, getTouchMoveDelta(x, y)); + mCurrentDragDirection, getTouchMoveDelta(x, y)); onScroll(); } else { if (isTouchInContentView(x, y)) { setDragState(STATE_DRAGGING); } } - mLastMotionX = x; mLastMotionY = y; break; @@ -433,9 +410,11 @@ public boolean onInterceptTouchEvent(MotionEvent ev) { @Override public boolean onTouchEvent(MotionEvent ev) { - if (preventSwipeBack(ev)) { + if(!mEnableSwipeBack){ + cancel(); return false; } + final int action = ev.getActionMasked(); if (action == MotionEvent.ACTION_DOWN) { @@ -462,20 +441,16 @@ public boolean onTouchEvent(MotionEvent ev) { case MotionEvent.ACTION_MOVE: { if (mDragState == STATE_IDLE) { - boolean shouldStartDrag = shouldStartDrag(x, y); - if (shouldStartDrag) { - setDragState(STATE_DRAGGING); - } + selectDragDirection(x, y); } else if (mDragState == STATE_DRAGGING) { mViewMoveAction.move(this, mContentView, mViewOffsetHelper, - mDragDirection, getTouchMoveDelta(x, y)); + mCurrentDragDirection, getTouchMoveDelta(x, y)); onScroll(); } else { if (isTouchInContentView(x, y)) { setDragState(STATE_DRAGGING); } } - mLastMotionX = x; mLastMotionY = y; break; @@ -504,10 +479,10 @@ public boolean onTouchEvent(MotionEvent ev) { private void releaseViewForPointerUp() { mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity); - int moveEdge = mViewMoveAction.getEdge(mDragDirection); + int moveEdge = mViewMoveAction.getEdge(mCurrentDragDirection); float v; - if(mDragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT || - mDragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT){ + if(mCurrentDragDirection == DRAG_DIRECTION_LEFT_TO_RIGHT || + mCurrentDragDirection == DRAG_DIRECTION_RIGHT_TO_LEFT){ v = clampMag(mVelocityTracker.getXVelocity(), mMinVelocity, mMaxVelocity); }else{ v = clampMag(mVelocityTracker.getYVelocity(), mMinVelocity, mMaxVelocity); @@ -515,11 +490,11 @@ private void releaseViewForPointerUp() { if (moveEdge == EDGE_LEFT || moveEdge == EDGE_RIGHT) { int target = mViewMoveAction.getSettleTarget(this, mContentView, - v, mDragDirection, mScrollThreshold); + v, mCurrentDragDirection, mScrollThreshold); settleContentViewAt(target, 0, (int) v, 0); } else { int target = mViewMoveAction.getSettleTarget(this, mContentView, - v, mDragDirection, mScrollThreshold); + v, mCurrentDragDirection, mScrollThreshold); settleContentViewAt(0, target, 0, (int) v); } } @@ -598,7 +573,7 @@ private int computeSettleDuration(int dx, int dy, int xvel, int yvel) { final float yweight = yvel != 0 ? (float) absYVel / addedVel : (float) absDy / addedDistance; - int range = mViewMoveAction.getDragRange(this, mDragDirection); + int range = mViewMoveAction.getDragRange(this, mCurrentDragDirection); int xduration = computeAxisDuration(dx, xvel, range); int yduration = computeAxisDuration(dy, yvel, range); @@ -714,7 +689,7 @@ private void drawScrim(Canvas canvas, View child) { final int baseAlpha = (mScrimColor & 0xff000000) >>> 24; final int alpha = (int) (baseAlpha * mScrimOpacity); final int color = alpha << 24 | (mScrimColor & 0xffffff); - int movingEdge = mViewMoveAction.getEdge(mDragDirection); + int movingEdge = mViewMoveAction.getEdge(mCurrentDragDirection); if ((movingEdge & EDGE_LEFT) != 0) { canvas.clipRect(0, 0, child.getLeft(), getHeight()); } else if ((movingEdge & EDGE_RIGHT) != 0) { @@ -730,7 +705,7 @@ private void drawScrim(Canvas canvas, View child) { private void drawShadow(Canvas canvas, View child) { - int movingEdge = mViewMoveAction.getEdge(mDragDirection); + int movingEdge = mViewMoveAction.getEdge(mCurrentDragDirection); if ((movingEdge & EDGE_LEFT) != 0) { mShadowLeft.setBounds(child.getLeft() - mShadowLeft.getIntrinsicWidth(), child.getTop(), child.getLeft(), child.getBottom()); @@ -763,18 +738,18 @@ public void computeScroll() { private void onSwipeBackBegin() { mIsScrollOverValid = true; - mScrimOpacity = 1 - mViewMoveAction.getCurrentPercent(this, mContentView, mDragDirection); + mScrimOpacity = 1 - mViewMoveAction.getCurrentPercent(this, mContentView, mCurrentDragDirection); if (mListeners != null && !mListeners.isEmpty()) { for (SwipeListener listener : mListeners) { - listener.onSwipeBackBegin(mDragDirection, mViewMoveAction.getEdge(mDragDirection)); + listener.onSwipeBackBegin(mCurrentDragDirection, mViewMoveAction.getEdge(mCurrentDragDirection)); } } invalidate(); } private void onScroll() { - mScrollPercent = mViewMoveAction.getCurrentPercent(this, mContentView, mDragDirection); - mScrimOpacity = 1 - mViewMoveAction.getCurrentPercent(this, mContentView, mDragDirection); + mScrollPercent = mViewMoveAction.getCurrentPercent(this, mContentView, mCurrentDragDirection); + mScrimOpacity = 1 - mViewMoveAction.getCurrentPercent(this, mContentView, mCurrentDragDirection); if (mScrollPercent < mScrollThreshold && !mIsScrollOverValid) { mIsScrollOverValid = true; } @@ -785,7 +760,7 @@ private void onScroll() { } if (mListeners != null && !mListeners.isEmpty()) { for (SwipeListener listener : mListeners) { - listener.onScroll(mDragDirection, mViewMoveAction.getEdge(mDragDirection), mScrollPercent); + listener.onScroll(mCurrentDragDirection, mViewMoveAction.getEdge(mCurrentDragDirection), mScrollPercent); } } invalidate(); @@ -803,15 +778,13 @@ private void onViewDragStateChanged(int dragState) { if (mListeners != null && !mListeners.isEmpty()) { for (SwipeListener listener : mListeners) { listener.onScrollStateChange(dragState, - mViewMoveAction.getCurrentPercent(this, mContentView, mDragDirection)); + mViewMoveAction.getCurrentPercent(this, mContentView, mCurrentDragDirection)); } } } - public static SwipeBackLayout wrap(View child, int dragDirection, - ViewMoveAction viewMoveAction, Callback callback) { + public static SwipeBackLayout wrap(View child, ViewMoveAction viewMoveAction, Callback callback) { SwipeBackLayout wrapper = new SwipeBackLayout(child.getContext()); - wrapper.setDragDirection(dragDirection); wrapper.addView(child, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); wrapper.setContentView(child); @@ -820,10 +793,8 @@ public static SwipeBackLayout wrap(View child, int dragDirection, return wrapper; } - public static SwipeBackLayout wrap(Context context, int childRes, int dragDirection, - ViewMoveAction viewMoveAction, Callback callback) { + public static SwipeBackLayout wrap(Context context, int childRes, ViewMoveAction viewMoveAction, Callback callback) { SwipeBackLayout wrapper = new SwipeBackLayout(context); - wrapper.setDragDirection(dragDirection); View child = LayoutInflater.from(context).inflate(childRes, wrapper, false); wrapper.addView(child, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); @@ -864,9 +835,8 @@ public static void updateLayoutInSwipeBack(View view) { } public interface Callback { - boolean shouldBeginDrag(SwipeBackLayout swipeBackLayout, float downX, float downY, int dragDirection); - - boolean canSwipeBack(SwipeBackLayout swipeBackLayout, int dragDirection, int moveEdge); + int getDragDirection(SwipeBackLayout swipeBackLayout, ViewMoveAction moveAction, + float downX, float downY, float dx, float dy, float touchSlop); } public interface ViewMoveAction { diff --git a/arch/src/main/res/values/attrs.xml b/arch/src/main/res/values/attrs.xml index 662c5cb22..f443b5530 100644 --- a/arch/src/main/res/values/attrs.xml +++ b/arch/src/main/res/values/attrs.xml @@ -17,12 +17,6 @@ - - - - - - diff --git a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDArchTestFragment.java b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDArchTestFragment.java index cf119a955..8c04e68e9 100644 --- a/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDArchTestFragment.java +++ b/qmuidemo/src/main/java/com/qmuiteam/qmuidemo/fragment/lab/QDArchTestFragment.java @@ -25,10 +25,12 @@ import android.widget.TextView; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.qmuiteam.qmui.arch.QMUIFragment; import com.qmuiteam.qmui.arch.QMUINavFragment; +import com.qmuiteam.qmui.arch.SwipeBackLayout; import com.qmuiteam.qmui.arch.annotation.LatestVisitRecord; import com.qmuiteam.qmui.arch.record.RecordArgumentEditor; import com.qmuiteam.qmui.util.QMUIViewHelper; @@ -162,6 +164,22 @@ protected void onFragmentResult(int requestCode, int resultCode, Intent data) { } } + @Override + protected int getDragDirection(@NonNull SwipeBackLayout swipeBackLayout, + @NonNull SwipeBackLayout.ViewMoveAction viewMoveAction, + float downX, float downY, float dx, float dy, float slopTouch) { + if(dx >= slopTouch){ + return SwipeBackLayout.DRAG_DIRECTION_LEFT_TO_RIGHT; + }else if(-dx>= slopTouch){ + return SwipeBackLayout.DRAG_DIRECTION_RIGHT_TO_LEFT; + } else if(dy >= slopTouch){ + return SwipeBackLayout.DRAG_DIRECTION_TOP_TO_BOTTOM; + }else if(-dy >= slopTouch){ + return SwipeBackLayout.DRAG_DIRECTION_BOTTOM_TO_TOP; + } + return SwipeBackLayout.DRAG_DIRECTION_NONE; + } + public static void injectEntrance(final QMUITopBarLayout topbar) { topbar.addRightTextButton("new Activity", QMUIViewHelper.generateViewId()) .setOnClickListener(new View.OnClickListener() {