zoukankan      html  css  js  c++  java
  • android 自定义控件之ViewGroup生命周期执行步骤

    前言
      了解ViewGroup的生命周期的执行步骤对于自己自定义ViewGroup的时候十分重要,清楚了整个流程才能对ViewGroup有更深的理解。本文从个人的总结,来阐述一下执行的顺序。

    执行说明

      首先ViewGroup的常用的生命周期主要有:构造方法、onLayout()、onFinishInflate()、onMeasure()、onSizeChanged(),前两种在创建ViewGroup子类的时候,必须重写。至于draw()和drawChild()是其用来绘制背景和子View用的,就不在生命周期里一一叙述。

    第一种:在xml里直接引用的,执行顺序一般是:构造方法->onFinishInflate()(只执行一次)->onMeasure()(可能多次执行)->onSizeChanged()(在重新onMeasure的时候发现跟之前测量的尺寸不一样的时候就会回调此方法)->onLayout()(布置子View)->onMeasure()->onLayout().......
     
    第二种:在Activity中setContentView( newCustomView(this))引用的,执行顺序与第一种相比,除了构造方法引用的不一致和不执行onFinishInflate()外,其他基本一致。
     
    第三种:在Activity中直接new CustomView(this)而且不添加任何父布局的时候只会执行构造方法,其它不会执行。

    总结技巧:

    onMeasure()里一般是定义子控件的测量尺寸和宽高。
    首先设置ViewGroup自身的尺寸如下:

    int widthSize = MeasureSpec.getSize(widthMeasureSpec);  
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);  
    setMeasuredDimension(widthSize, heightSize);
    

    然后设置子View的尺寸例如下面:

    View leftMenuView = getChildAt(1);  
    MarginLayoutParams lp = (MarginLayoutParams)  
                    leftMenuView.getLayoutParams();  
    final int drawerWidthSpec = getChildMeasureSpec(widthMeasureSpec,  
                    mMinDrawerMargin + lp.leftMargin + lp.rightMargin,  
                    lp.width);  
    final int drawerHeightSpec = getChildMeasureSpec(heightMeasureSpec,  
                    lp.topMargin + lp.bottomMargin,  
                    lp.height);  
    leftMenuView.measure(drawerWidthSpec, drawerHeightSpec);  
      
    View contentView = getChildAt(0);  
    lp = (MarginLayoutParams) contentView.getLayoutParams();  
    final int contentWidthSpec = MeasureSpec.makeMeasureSpec(  
                    widthSize - lp.leftMargin - lp.rightMargin, MeasureSpec.EXACTLY);  
    final int contentHeightSpec = MeasureSpec.makeMeasureSpec(  
                    heightSize - lp.topMargin - lp.bottomMargin, MeasureSpec.EXACTLY);  
    contentView.measure(contentWidthSpec, contentHeightSpec);
    

    int getChildMeasureSpec(int spec,int padding,int childDimension) 返回的是测量尺寸规格spec,可以给子View设置padding,不需要设置padding就直接如contentView一样。
    onLayout()布局子view的位置,基本上用到layout(left,top,right,bottom);

    getWidth()和getMeasureWidth()的区别与联系:
    getMeasuredWidth(): 只要一执行完 setMeasuredDimension() 方法,就有值了,并且不再改变。简单来说执行完onMeasure里的方法后就可以获取;
    getWidth()只有在执行onMeasure()之后才能获取,但是可能应为布局大小调整发生变化,如果onLayout()没有对子View的宽高进行修改,那么两个值相等。

    生命周期表:

    参考:http://blog.csdn.net/anydrew/article/details/50985763

  • 相关阅读:
    Apache ab压力测试
    2、Android自动测试之Monkey工具
    1、Monkey环境搭建
    解决IDEA中,maven依赖不自动补全的问题
    Centos7解决在同一局域网内无法使用ssh连接
    sql草稿
    mysql三表联合查询,结果集合并
    vue:父子组件间通信,父组件调用子组件方法进行校验子组件的表单
    vue:使用不同参数跳转同一组件,实现动态加载图片和数据,以及利用localStorage和vuex持久化数据
    vue:解决使用param传参后,再次刷新页面会新增一个原有的tab
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/6706765.html
Copyright © 2011-2022 走看看