簡介
這個小東西是我很早之前寫的,功能就是可以給你的頁面帶上滑動返回。開始的時候沒在意,後來發現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;
}
}
});
複製程式碼
大概的步驟就是這樣子...
總結
大家有什麼疑問或者建議都可以在下面評論告訴我,或者上GitHub上提issue,謝謝大家,祝大家新年快樂~