1. 程式人生 > >側滑回退的layout(類似IOS側滑回退到上一個activity)

側滑回退的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滑動了,但是滑動的背後是全白的

,這個就是真正頂級View的背景色,所以說到這裡,大家知道該怎麼做了吧?把Activity主題設定成透明的就ok啦,但是注意要把layout的背景設定成白色。


大功告成啦,上圖:


下次有時間給大家分享一個懸浮效果的簡單案例:


詳情可以關注https://github.com/ray0807

https://github.com/ray0807/ShareFramework/blob/master/balloon/simplifyCorelibs/src/main/java/com/corelibs/views/SplideBackLinearLayout.java