側滑回退的layout(類似IOS側滑回退到上一個activity)
用過apple的同學應該都知道,大多數IOS應用都支援側滑回退,就不詳細說明了,直接上圖:
作為使用ios的android開發者來說,我是特別喜歡這個功能的,既然這樣,那就在android上也實現這個功能吧。
構思:
1、要處理滑動事件,而且優先順序比較高,所以必須在父View中處理,也就是我們layout中的頂級View(當然這裡說的頂級View不是DecorView,僅僅是layout裡面的第一層View),一般是ViewGroup。
2、既然是ViewGroup,我們得思考下,這個滑動事件我們是在哪個方法裡處理,有同學說了,onTouchEvent(),OK,我們再分析下,假如我們在onTouchEvent()中處理,由view的事件分發我們可以知道:
我們知道了這個循序以後,所以我們得選擇優先處理事件的方法,這個就可以從onInterceptTouchEvent()和dispatchTouchEvent()中選,這裡我選擇了dispatchTouchEvent(),為什麼,我也不知道...
3、實現原理
只有橫向滑動才處理,並且,只有從邊緣滑動才能觸發此事件,其實這就簡單了,直接上程式碼。
@Override public boolean dispatchTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: startX = event.getX(); //判斷是否是從邊緣滑動 //不是,此事件繼續向下分發 if (startX <= OFFSET_DISTANCE) { return true; } else { super.dispatchTouchEvent(event); } case MotionEvent.ACTION_MOVE: if (startX <= OFFSET_DISTANCE) { currentX = (int) event.getX(); distanceX = (int) (currentX - startX); mScroller.startScroll(-currentX, 0, -distanceX, 0); invalidate(); } break; case MotionEvent.ACTION_UP: if (startX <= OFFSET_DISTANCE) { endX = event.getX(); //判斷是否到達關閉activity的閥值 if (endX - startX > BACK_DISTANCE) { //是 通過介面回撥 if (callback != null) { mScroller.startScroll(-currentX, 0, -(getScreentWidth() - currentX), 0); callback.invokeBack(); } else { mScroller.startScroll(0, 0, 0, 0); } } else { mScroller.startScroll(0, 0, 0, 0); } invalidate(); } break; } return super.dispatchTouchEvent(event); }
<pre name="code" class="java"> public void setBackListener(BackViewInterface callback) {
this.callback = callback;
}
public interface BackViewInterface {
void invokeBack();
}
使用方式:
1、在BaseActivity中實現介面
2、在子activity中的使用
千萬不要忘了在子activity中註冊介面
3 、特別注意
由於我們僅僅是滑動的View而在上面提到的真正的頂級view還是沒動,沒動會帶來什麼問題呢,雖然棧頂activity的View滑動了,但是滑動的背後是全白的
大功告成啦,上圖:
下次有時間給大家分享一個懸浮效果的簡單案例:
詳情可以關注https://github.com/ray0807
https://github.com/ray0807/ShareFramework/blob/master/balloon/simplifyCorelibs/src/main/java/com/corelibs/views/SplideBackLinearLayout.java