自定义View之侧滑菜单

側拉菜单
一:是一个组合控件,用viewgroup 关心,onmesure和onlayout方法
步骤:
1.自定义控件的类继承自viewgroup,实现onlayout方法
2.布局---viewgroup(第一个添加的索引是0)
2.1.菜单布局(scrollview)和主界面布局

2.2.引入布局,用关键字 

3.在onMeasure 方法中测量菜单和主界面的宽和高MeasureSpec.getsize(),getmode();创建规格makemeasureSpec();[1,EXACTY;2,AT_MOST].
3.1测量菜单 getchildAt(0);measure(getlayoutParams(),width,height);
3.2测量主界面
getchildAt(1);//获得对象
4,在onlayout方法中给菜单和主界面设置位置
4.1 主界面的位置放置在屏幕的左上角:mainView.layout(0,0,r,b);
4.2 菜单的位置放置在窗体的左边:menuView.layout(-getmeasuredWidth(),t,0,b);
5, onTouchEvent()
5.1 scrollto和scrollby
5.2 获取已经移动的增量
6,处理触摸事件的内容
6.1,获取当前按下的位置getX();
在move过程中,设置增量值,dx = downX - moveX;
判断dx的大小,如果num=getSrollX()+dx<-侧边菜单的宽度.
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();

}
回调
public void computeScroll() {
if (scroller.computeScrollOffset()) {
int currX = scroller.getCurrX();//获取模拟的当前位置
scrollTo(currX,0);
invalidate();//回调
}
}
事件分发处理:
scaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
/**

  • 解决事件分发问题

  • @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方法里面给它设置的值

该方法获取的是在代码里测量出来的宽度。

getWidth
获取的时机:layout流程走完以后才可以获取到值,
值的计算方式:right - left(也就是onLayout方法的right参数减去left参数得到的值)

次方法获取的是最终显示到界面上的宽度。

通常情况下,如果这两个方法都能获取到值的话,这两个值是一样的,但是,如果当前的自定义控件是一个2B程序员写的,在layout流程里没有根据
测量的宽高来设置控件的显示位置,这两个值可能不一样。

更改主题:
AS里面的两种方式
1.在清单文件中的APPTHEM 里面,修改Theme.AppCompat.Light.DarkActionBar为Theme.AppCompat.Light.NoActionBar
2.在main里面配置
ActionBar supportActionBar = getSupportActionBar();
if (supportActionBar != null) {
getSupportActionBar().hide();
}

你可能感兴趣的:(自定义View之侧滑菜单)