1. 程式人生 > >側滑選單自定義SlideMenu

側滑選單自定義SlideMenu

=側滑選單========

在這裡插入圖片描述

SlidingMenu 是GitHub上的一個開源專案,用來實現SlidingMenu的選單效果。
Sliding Menu的是一種比較新的設定介面或配置介面效果,在主介面左滑或者右滑出現設定介面,能方便的進行各種操作
,還是GitHub上的開源專案SlidingMenu提供了最佳的實現:定製靈活、各種陰影和漸變的滑動效果也很
左滑和右滑出現選單,用一個引數就可以簡單配置。
menu.setMode(SlidingMenu.LEFT);

這是一個開源庫,而不是一個完整的專案,把它作為libary引入到你自己的工程裡,簡單配置一下就可以實現SlidingMenu的效果。
1.自定義SlideMenu,繼承自ViewGroup

2.編寫menu和main介面的佈局,然後include到SlideMenu中,作為它的子view

3.在onFinishInflate方法中通過getChildAt(0)來初始化menuView和mainView物件

4.在onSizeChanged方法中獲取menuView和mainView的寬高

5.自己實現onMeasure方法,主要了解測量規則MeasureSpec如果建立,以及三種測量mode的含義

6.由於自己實現onMeasure方法太麻煩和繁瑣,最後將SlideMenu繼承自FrameLayout,原因如下:
a.因為FrameLayout幫我們實現了onMeasure方法,不需要我們自己實現
b.因為FrameLayout程式碼最少,在四大布局中屬於輕量級

7.由於FrameLayout是按照自己的方式實現onLayout方法,而我們的需求是將menuView放在螢幕左邊,
所以需要自己重寫onLayout方法:
menuView.layout(-menuWidth, 0, 0, menuHeight);
mainView.layout(0, 0, mainWidth, menuHeight);

8.當TouchMove的時候讓SlideMenu跟隨手指滑動
tip1:在ViewGorup中讓子view移動的方法:
layout(l,t,r,b);
offsetTopAndBottom(offset)和offsetLeftAndRight(offset);
scrollTo和scrollBy;

tip2:scrollTo和scrollBy表示的不是view本身的移動,而是指螢幕的移動
a.在onTouchEvent方法中計算出手指移動的距離
b.根據手指移動的距離和當前螢幕已經滾動的scrollX的座標算出新的scrollX:
int newScrollX = (int) (getScrollX()-deltaX);
c.對SlideMenu進行左邊和右邊的限定
if(newScrollX<-menuWidth){
newScrollX = -menuWidth;//限制左邊
}
if(newScrollX>0){
newScrollX = 0;//限制右邊
}

9.當TouchUp的時候緩慢滑動SlideMenu到指定位置
tip3:Scroller: 是用來模擬滾動的,模擬了一個滾動的流程,然後在滾動過程中也計算好了當前應該
滾動的scrollX和scrollY。
我們需要在它的執行過程中獲得當前的scrollX和scrollY,然後自己去scrollTo(scrollX,scrollY);
a.使用Scroller處理緩慢滾動:
scroller.startScroll(getScrollX(), 0, 0-getScrollX(), 0,400);
// Invalidate to request a redraw
invalidate();
b.在computeScroll方法中不斷獲取當前的currX和currY,然後自己去scrollTo
if(scroller.computeScrollOffset()){//如果返回true,表示動畫沒有結束,反之就結束
scrollTo(scroller.getCurrX(), scroller.getCurrY());
invalidate();
}

10.此時出現滑動bug,當在menu中的ScrollView中水平滑動時無法滑動SlideMenu,
a.根據觸控事件的傳遞機制分析原因,傳遞機制詳情見圖
b.只要我們攔截觸控事件,就會將Event傳給onTouchEvent,從而可以滑動
c.但是我們要在一定條件下才能攔截,在move的方向偏於水平方向的時候攔截
d.在onInterceptTouchEvent方法中計算x和y方向的移動距離,並比較是偏於水平還是垂直