給你的頁面帶上側滑返回——SlideBack
這個小東西是我很早之前寫的,功能就是可以給你的頁面帶上滑動返回。開始的時候沒在意,後來發現star的人還不少...
於是我決定完善完善,然後寫個部落格介紹介紹...
GitHub地址: SlideBack
效果如下:

使用方法
Step 1. 在你專案的根build.gradle中新增jitpack.io庫
allprojects { repositories { ... maven { url 'https://jitpack.io' } } } 複製程式碼
Step 2. 新增SlideBack的依賴
dependencies { implementation 'com.github.ChenTianSaber:SlideBack:v0.8.1' } 複製程式碼
Step 3. 將專案中繼承的Activity換成SlideBackActivity
public class YourActivity extends SlideBackActivity 複製程式碼
Step 4. 你可以在onCreate方法中呼叫setSlideBackDirection,可以給每一個Activity單獨配置,如果沒有配置這個,那麼預設是 SlideBackActivity.ALL
protected void onCreate(Bundle savedInstanceState) { //Other Code... //有三個值可以設定 //SlideBackActivity.RIGHT表示只能從螢幕右側滑出 //SlideBackActivity.LEFT表示只能從螢幕左側滑出 //SlideBackActivity.ALL表示從螢幕兩邊都可以滑出 setSlideBackDirection(SlideBackActivity.RIGHT); } 複製程式碼
Step 5. 重寫slideBackSuccess(當滑動有效時會回撥這個方法,可以在這裡進行回退操作或其他)
@Override protected void slideBackSuccess() { finish();//或者其他 } 複製程式碼
實現原理
原理很簡單,具體的大家可以上GitHub看原始碼,沒幾行程式碼,很短噠
至於這篇文章裡,我就簡單的講一下好了:
Step 1.首先我們畫一個自定義view,就是你從螢幕邊緣拉出來的那個東西,我們將其稱為 側滑View 好了

這個View只有一個可變的引數,就是View的寬度。其餘所有的座標都是根據這個寬度來計算的,於是我們只要改變這個寬度就可以做出一種動畫的效果
Step 2.然後我們獲取DecorView,並將上面的這個側滑View新增進去,關鍵程式碼如下:
FrameLayout container = (FrameLayout) getWindow().getDecorView(); containerView = LayoutInflater.from(this).inflate(R.layout.chentian_view_slide_container, null); slideContainerView = containerView.findViewById(R.id.slide_container); slideContainerView.addView(backView); container.addView(slideContainerView); 複製程式碼
Step 3.最後一步就是監聽DecorView的Touch事件,來判斷滑動的區域以及滑動距離來設定側滑View的引數,關鍵程式碼如下:
slideContainerView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { x = Math.abs(screenWidth * offset - motionEvent.getRawX()); y = motionEvent.getRawY(); switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: downX = motionEvent.getRawX(); //判斷點選範圍與設定的滑出區域是否符合 if (SLIDEBACK_DIRECTION == LEFT) { if (downX > screenWidth / 2) { //在右側區域,直接return return false; } else { offset = 0; } } else if (SLIDEBACK_DIRECTION == RIGHT) { if (downX < screenWidth / 2) { //在左側區域,直接return return false; } else { offset = 1; } } else if (SLIDEBACK_DIRECTION == ALL) { if (downX > screenWidth / 2) { //在右側區域,設為RIGHT offset = 1; } else if (downX < screenWidth / 2) { //在左側區域,設為LEFT offset = 0; } } x = Math.abs(screenWidth * offset - motionEvent.getRawX()); if (x <= dp2px(CANSLIDE_LENGTH)) { isEage = true; slideBackView.updateControlPoint(Math.abs(x), offset); setBackViewY(backView, (int) (motionEvent.getRawY())); } break; case MotionEvent.ACTION_MOVE: float moveX = Math.abs(screenWidth * offset - x) - downX; if (isEage) { if (Math.abs(moveX) <= shouldFinishPix) { slideBackView.updateControlPoint(Math.abs(moveX) / 2, offset); } setBackViewY(backView, (int) (motionEvent.getRawY())); } break; case MotionEvent.ACTION_UP: //從左邊緣划過來,並且最後在螢幕的三分之一外 if (isEage) { if (x >= shouldFinishPix) { slideBackSuccess(); } } isEage = false; slideBackView.updateControlPoint(0, offset); break; } if (isEage) { return true; } else { return false; } } }); 複製程式碼
大概的步驟就是這樣子...