Activity簡單幾步支持向右滑動返回
向右滑動返回,對于屏幕過大的手機來說,在單手操作時,是一個不錯的用戶體驗,用戶不必再費力的或者用另一個手去點擊屏幕左上角的返回按鈕或者,手機右下角的返回按鈕,輕輕向右滑動屏幕即可返回上一頁,這個功能如今大部分APP都已經支持啦,你的APP支持了嗎?
自己在網上百度了一些滑動返回的方法,有的是用的第三方控件如swipebackLayout但弊端過大如與自己自定義的一些控件沖突等,有的是 通過判斷手勢監聽但步驟相當繁瑣,總之沒有盡如人意的,本篇所講的實現方法其實也是通過監聽事件分發來實現的,但是步驟非常簡單,且效果經本人不斷測試也 相當不錯,接下來本人講解下實現過程:
實現該功能需同時滿足幾個條件,并要考慮用戶的操作意圖,既要保證足夠的靈敏度,不要出現向右滑動好多次還沒返回上一頁的情況,也不要出現本來是想上下滑動(斜著上下滑動)而非向右滑動返回,也被判斷為向右滑動返回而結束了當前界面,那么我們需要滿足:
1.用戶需向右滑動一段距離,且X軸距離>某一設定的值;
2.因為向右滑動時,不可能時嚴格的水平方向而不向Y軸偏移,所以向Y軸的偏移量不能超過某一設定的值,否則認為用戶意圖不是滑動返回而是上下滑動;
3.在測試過程中,如果用戶意圖是上下滑動時,那么手指在y軸移動速度(我們按每秒移動的像素值,可通過VelocityTracker類計算) 非常大,通常在幾千到過萬,而在正常的水平滑動時,y軸的移動速度通常只有100左右,因此,我們需要判斷的是,如果y軸上手指滑動速度超過某一設定值 (本人將該值設置為了1000),則認為用戶意圖是上下滑動而非向右滑動返回;
好了,接下來我們便可自定義一個SlideBackActivity繼承Activity,并在SlideBackActivity中重寫事件分發dispatchTouchEvent,并記錄手指按下,移動的距離及手指滑動速度,從而判斷用戶的意圖,完整代碼:
/**
- 支持滑動返回
- 繼承該Activity則支持滑動返回
- @author 白玉梁
*/
public class SlideBackActivity extends Activity{
//手指上下滑動時的最小速度
private static final int YSPEED_MIN = 1000;
//手指向右滑動時的最小距離
private static final int XDISTANCE_MIN = 50;
//手指向上滑或下滑時的最小距離
private static final int YDISTANCE_MIN = 100;
//記錄手指按下時的橫坐標。
private float xDown;
//記錄手指按下時的縱坐標。
private float yDown;
//記錄手指移動時的橫坐標。
private float xMove;
//記錄手指移動時的縱坐標。
private float yMove;
//用于計算手指滑動的速度。
private VelocityTracker mVelocityTracker;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
} /**createVelocityTracker(event); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: xDown = event.getRawX(); yDown = event.getRawY(); break; case MotionEvent.ACTION_MOVE: xMove = event.getRawX(); yMove= event.getRawY(); //滑動的距離 int distanceX = (int) (xMove - xDown); int distanceY= (int) (yMove - yDown); //獲取順時速度 int ySpeed = getScrollVelocity(); //關閉Activity需滿足以下條件: //1.x軸滑動的距離>XDISTANCE_MIN //2.y軸滑動的距離在YDISTANCE_MIN范圍內 //3.y軸上(即上下滑動的速度)<XSPEED_MIN,如果大于,則認為用戶意圖是在上下滑動而非左滑結束Activity if(distanceX > XDISTANCE_MIN &&(distanceY<YDISTANCE_MIN&&distanceY>-YDISTANCE_MIN)&& ySpeed < YSPEED_MIN) { finish(); } break; case MotionEvent.ACTION_UP: recycleVelocityTracker(); break; default: break; } return super.dispatchTouchEvent(event);
- 創建VelocityTracker對象,并將觸摸界面的滑動事件加入到VelocityTracker當中。 *
- @param event
/
private void createVelocityTracker(MotionEvent event) {
if (mVelocityTracker == null) {
} mVelocityTracker.addMovement(event); } /**mVelocityTracker = VelocityTracker.obtain();
- 回收VelocityTracker對象。 / private void recycleVelocityTracker() { mVelocityTracker.recycle(); mVelocityTracker = null; } /**
- @return 滑動速度,以每秒鐘移動了多少像素值為單位。
*/
private int getScrollVelocity() {
mVelocityTracker.computeCurrentVelocity(1000);
int velocity = (int) mVelocityTracker.getYVelocity();
return Math.abs(velocity);
}
}</pre>