自定义View学习

一、自定义控件流程

onMeasure()  ----> onLayout  ------->onDraw()

每个view的绘制流程包含三个阶段,一是测量过程,二是布局过程,三是绘制过程(展现在屏幕上)

1、页面加载过程中,从最上层viewGroup开始,逐层向下递归,父布局调用子布局的measure()方法,measure()方法是一个调度方法,它会调用子View的onMeasure()方法,如果子View是ViewGroup,则依次向下递归调用子View的measure()方法,如果子View是View而不是ViewGroup,那么该子View会调用自己的onMeasure()方法,在方法中测量自己的宽高信息,然后交给父布局存储下该子View的宽高信息。

2、接下来是父布局调用子布局的layout()方法,layout()方法时一个调度方法,它会调用子View的onLayout()方法,如果子View是ViewGroup,那么会依次递归调用子View的onLayout()方法,如果子View是View而不是ViewGroup,那么该子View会调用自己的onLayout()方法,在父布局调用子布局的layout时候,会将子View存在父布局的宽高信息传递给子View。

下面是一个自定义正方形ImageView的例子:

public class SquareImageViewextends AppCompatImageView {

public SquareImageView(Context context) {

    this(context,null);

}

public SquareImageView(Context context, AttributeSet attrs) {

            super(context, attrs);

    }

@Override

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        //使用这个方法的setMeasuredDimension()方法,将宽高设置进去

          super.onMeasure(widthMeasureSpec, heightMeasureSpec);

          //获取设置的宽和高

          int measuredWidth = getMeasuredWidth();

          int measuredHeight = getMeasuredHeight();

          //定义自己的宽高设置方法

          if (measuredWidth > measuredHeight){

             measuredWidth=measuredHeight;

            }else {

             measuredHeight=measuredWidth;

            }

      //定义好宽高规则后,需要调用setMeasuredDimension()方法,将实际宽高设置给父布局

        setMeasuredDimension(measuredWidth,measuredHeight);

    }

}

在例子中,重写onMeasure()方法,需要先调用 super.onMeasure(widthMeasureSpec, heightMeasureSpec);方法,触发父类的setMeasuredDimension方法,得到测量的宽高,然后调用getMeasuredWidth、getMeasuredHeight方法,来获取通过setMeasuredDimension方法设置好的宽高信息,然后接下来就是定义自己的宽高规则,最后一步很重要,需要调用setMeasuredDimension()方法,将设置好的宽高规则传递给父布局。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容