Android滑動返回-swipebacklayout解析
互動效果
背景
ios7釋出時有滑動返回手勢操作,產品經理看到後很興奮,立即要求android增加相同手勢操作。由於android系統特性,並不支援兩個activity的滑動操作。經過一番研究和掙扎,終於實現了效果。實現原理基本和下文要分析的swipebacklayout類似,我們直接來分析swipebacklayout。
使用方法
使用方法很簡單,activity繼承SwipeBackActivity就可以了。
實現原理
假設場景
有兩個activity – A 和 B,B在A上層 ,手指滑動B返回到A。
實現原理
手指移動B頁面的view,因為B被設定為透明,所以會看到A。
分析
swipebacklayout佈局對比
使用swipebacklayout的activity
普通activity佈局
可以看到,使用了swipebacklayout的activity會在DecorView中增加一層SwipeBackLayout(FrameLayout)。檢視跟隨手指滑動就是通過SwipeBackLayout來實現的。我們結合程式碼來看。
佈局增加SwipeBackLayout(FrameLayout)
SwipeBackActivity
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mHelper.onPostCreate();
}
SwipeBackActivityHelper
public void onPostCreate() {
// 在DecorView下增加SwipeBackLayout(FragmentLayout)
mSwipeBackLayout.attachToActivity(mActivity);
}
SwipeBackLayout
public void attachToActivity(Activity activity) {
mActivity = activity;
TypedArray a = activity.getTheme().obtainStyledAttributes(new int[]{
android.R.attr.windowBackground
});
int background = a.getResourceId(0, 0);
a.recycle();
// 在DecorView下增加SwipeBackLayout(FragmentLayout)
ViewGroup decor = (ViewGroup) activity.getWindow().getDecorView();
// 拿到第一個子view-decorChild
ViewGroup decorChild = (ViewGroup) decor.getChildAt(0);
decorChild.setBackgroundResource(background);
// 刪除子view-decorChild
decor.removeView(decorChild);
// 把子view-decorChild新增到SwipeBackLayout(FragmentLayout)下
addView(decorChild);
setContentView(decorChild);
// 把SwipeBackLayout(FragmentLayout)新增到DecorView下
decor.addView(this);
}
手指滑動,移動頁面
SwipeBackLayout
@Override
public boolean onTouchEvent(MotionEvent event) {
// 是否支援手勢返回
if (!mEnable) {
return false;
}
// 處理螢幕事件
mDragHelper.processTouchEvent(event);
return true;
}
ViewDragHelper.processTouchEvent(event),我們只分析主要的ACTION_MOVE事件。
case MotionEvent.ACTION_MOVE: {
if (mDragState == STATE_DRAGGING) {
// 計算位置
final int index = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, index);
final float y = MotionEventCompat.getY(ev, index);
final int idx = (int) (x - mLastMotionX[mActivePointerId]);
final int idy = (int) (y - mLastMotionY[mActivePointerId]);
// 移動view
dragTo(mCapturedView.getLeft() + idx, mCapturedView.getTop() + idy, idx, idy);
saveLastMotion(ev);
} else {
// Check to see if any pointer is now over a draggable view.
// 省略不需要關注的程式碼
......
}
break;
}
ViewDragHelper.dragTo移動view
private void dragTo(int left, int top, int dx, int dy) {
int clampedX = left;
int clampedY = top;
final int oldLeft = mCapturedView.getLeft();
final int oldTop = mCapturedView.getTop();
// 橫向移動-左右
if (dx != 0) {
clampedX = mCallback.clampViewPositionHorizontal(mCapturedView, left, dx);
mCapturedView.offsetLeftAndRight(clampedX - oldLeft);
}
// 縱向移動-上下
if (dy != 0) {
clampedY = mCallback.clampViewPositionVertical(mCapturedView, top, dy);
mCapturedView.offsetTopAndBottom(clampedY - oldTop);
}
// 回撥-處理邏輯
if (dx != 0 || dy != 0) {
final int clampedDx = clampedX - oldLeft;
final int clampedDy = clampedY - oldTop;
mCallback
.onViewPositionChanged(mCapturedView, clampedX, clampedY, clampedDx, clampedDy);
}
}
相關文章
- Android側滑(右滑、下拉)返回控制元件 - SwipeBackLayoutAndroid控制元件
- Swift全屏滑動返回Swift
- 仿 “即刻APP” 滑動返回的效果APP
- Android 設定TextView滑動滾動條和滑動效果AndroidTextView
- iOS 實現UINavigation全屏滑動返回(二)iOSUINavigation
- Android側滑返回分析和實現(不高仿微信)Android
- Android 禁止ViewPager左右滑動AndroidViewpager
- iOS 如何絲滑的側滑返回iOS
- vue-router 手勢滑動觸發返回Vue
- Android:巢狀滑動總結Android巢狀
- Android 自定義View 滑動解鎖AndroidView
- Android自定義滑動刻度尺Android
- MirrorSwipeLayout:自定義Layout,仿MIUI滑動返回(已開源)UI
- Android巢狀滑動邏輯淺析Android巢狀
- Android 的滑動分析以及各種實現Android
- android可以無限迴圈滑動的ViewPagerAndroidViewpager
- 演算法題:返回滑動視窗中的最大值演算法
- Activity側滑返回的實現原理
- Android View 滑動衝突解決方式以及原理AndroidView
- 【朝花夕拾】Android自定義View篇之(十一)View的滑動,彈性滑動與自定義PagerViewAndroidView
- Flutter 仿iOS側滑返回案例實現FlutteriOS
- overscroll-behavior-x限制瀏覽器預設滑動返回上一頁瀏覽器
- Android ViewPager Fragments滑動只重新整理當前頁AndroidViewpagerFragment
- NestedScrolling機制解析,自定義巢狀滑動你也可以巢狀
- Android | 玩轉AppBarLayout,設定scrollFlags滑動屬性詳解AndroidAPP
- uniapp---app滑動翻頁(上滑、下滑、左滑、右滑)APP
- 給你的頁面帶上側滑返回——SlideBackIDE
- Sentinel Go 核心統計結構滑動視窗的深度解析Go
- Android-返回桌面?退出程式?Android
- Android開發:RecyclerView平滑流暢的滑動到指定位置AndroidView
- 移動端左滑右滑元件元件
- 【Android】【init】解析init程式啟動過程Android
- 基於滑動場景解析RecyclerView的回收複用機制原理View
- 簡單介紹android實現可以滑動的平滑曲線圖Android
- android短視訊開發,仿三方軟體列表滑動Android
- jQuery 效果 – 滑動jQuery
- 滑動條:QSliderIDE
- Android系統啟動流程(二)解析Zygote程式AndroidGo
- Android入門教程 | DrawerLayout 側滑欄Android