側(cè)拉菜單
一:是一個組合控件,用viewgroup 關(guān)心,onmesure和onlayout方法
步驟:
1.自定義控件的類繼承自viewgroup,實現(xiàn)onlayout方法
2.布局---viewgroup(第一個添加的索引是0)
2.1.菜單布局(scrollview)和主界面布局
2.2.引入布局,用關(guān)鍵字 <include layout="@layout/名稱"/>
3.在onMeasure 方法中測量菜單和主界面的寬和高MeasureSpec.getsize(),getmode();創(chuàng)建規(guī)格makemeasureSpec();[1,EXACTY;2,AT_MOST].
3.1測量菜單 getchildAt(0);measure(getlayoutParams(),width,height);
3.2測量主界面
getchildAt(1);//獲得對象
4,在onlayout方法中給菜單和主界面設(shè)置位置
4.1 主界面的位置放置在屏幕的左上角:mainView.layout(0,0,r,b);
4.2 菜單的位置放置在窗體的左邊:menuView.layout(-getmeasuredWidth(),t,0,b);
5, onTouchEvent()
5.1 scrollto和scrollby
5.2 獲取已經(jīng)移動的增量
6,處理觸摸事件的內(nèi)容
6.1,獲取當前按下的位置getX();
在move過程中,設(shè)置增量值,dx = downX - moveX;
判斷dx的大小,如果num=getSrollX()+dx<-側(cè)邊菜單的寬度.
SrcollTo();如果大于0,進入主界面 ,運用scrollTo();
否則scrollBy(dx,0); downX = moveX;
case MotionEvent.ACTION_MOVE:
int moveX = (int) event.getX();
int diff = downX - moveX;
scrollX = getScrollX() + diff;
if (scrollX < -getChildAt(0).getMeasuredWidth()) {
scrollTo(-getChildAt(0).getMeasuredWidth(), 0);
} else if (scrollX > 0) {
scrollTo(0, 0);
} else {
scrollBy(diff, 0);
}
downX = moveX;
break;
在手指離開后進行判斷up:
int centerposition = -getChildAt(0).getMeasuredWidth() / 2;
if (scrollX > centerposition) {//回到主界面
// scrollTo(0,0);
SCREEN_STATUS = MAIN_VIEW;
} else if (scrollX < centerposition) {//回到菜單界面
// scrollTo(-getChildAt(0).getMeasuredWidth(),0);
SCREEN_STATUS = MEUM_VIEW;
}
switchScreen();
break;
方法:
private void switchScreen() {
int startX = getScrollX();//獲取當前位置
int addX = 0;//增量值
if (SCREEN_STATUS==MAIN_VIEW) {
addX = 0-startX;
}else if (SCREEN_STATUS==MEUM_VIEW) {
addX = -getChildAt(0).getMeasuredWidth() - startX;
}
scroller.startScroll(startX,0,addX,0,Math.abs(addX)*5);
invalidate();
}
回調(diào)
public void computeScroll() {
if (scroller.computeScrollOffset()) {
int currX = scroller.getCurrX();//獲取模擬的當前位置
scrollTo(currX,0);
invalidate();//回調(diào)
}
}
事件分發(fā)處理:
scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
/**
解決事件分發(fā)問題
@param ev
-
@return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_MOVE:
int moveX = (int) ev.getX();
int moveY = (int) ev.getY();int slopX = Math.abs(downX-moveX); int slopY = Math.abs(downY-moveY); if (slopX>scaledTouchSlop&& slopX>slopY) { return true; } break; case MotionEvent.ACTION_DOWN: downX = (int) ev.getX(); downY = (int) ev.getY(); break;
}
return super.onInterceptTouchEvent(ev);
}
注意事項:
getWidth & getMeasuredWidth(Height同理)
從獲取的時機和值的計算方式兩個方面來說。
getMeasuredWidth
獲取的時機: measure流程走完以后就可以獲取到值
值的計算方式: 就是你在onMeasure方法里面給它設(shè)置的值
該方法獲取的是在代碼里測量出來的寬度。
getWidth
獲取的時機:layout流程走完以后才可以獲取到值克伊,
值的計算方式:right - left(也就是onLayout方法的right參數(shù)減去left參數(shù)得到的值)
次方法獲取的是最終顯示到界面上的寬度。
通常情況下潮剪,如果這兩個方法都能獲取到值的話,這兩個值是一樣的衅疙,但是亚斋,如果當前的自定義控件是一個2B程序員寫的,在layout流程里沒有根據(jù)
測量的寬高來設(shè)置控件的顯示位置拂募,這兩個值可能不一樣庭猩。
更改主題:
AS里面的兩種方式
1.在清單文件中的APPTHEM 里面,修改Theme.AppCompat.Light.DarkActionBar為Theme.AppCompat.Light.NoActionBar
2.在main里面配置
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
getSupportActionBar().hide();
}