美文网首页
自定义View之侧滑菜单

自定义View之侧滑菜单

作者: 神山上人 | 来源:发表于2017-01-22 22:54 被阅读0次

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

    2.2.引入布局,用关键字 <include layout="@layout/名称"/>
    

    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之侧滑菜单

          本文链接:https://www.haomeiwen.com/subject/fjnobttx.html