View 绘制流程知识小结

xiaoxiao2021-02-28  8

今天我们来复习下View的绘制流程。View是Android中所有控件的基类,是控件的一种抽象,代表了一个控件。

Android进阶——Android视图工作机制之measure、layout、draw

一、View树的绘制流程

measure –> layout –> draw 测量 –> 布局 –>绘制 measure :测量出View的宽/高; layout:确定View最终宽/高四个顶点的位置; draw:将View绘制在屏幕上;

二、measure

1、ViewGroup.LayoutParams:

指定视图宽度、高度的参数有 match_parent、wrap_content、固定值(100dp)三种。

2、MeasureSpec:

测量规则,代表一个32位的int值,将SpecMode、SpecSize包装成一个int值来避免过多的对象内存分配;高2位代表SpecMode(测量模式), 低30位代表SpecSize(在某种测量模式下测量出的具体值)。

SpecMode 测量模式:

UNSPECIFIED: 父容器不对View有任何限制,要多大给多大,一般用于系统内部,表示一种测量状态。

EXACTLY: 父容器检测出View所需要的精确大小,这时候View的值就是SpecSize;它对应于LayoutParams中的 match_parent 和 具体的数值两种模式。

AT_MOST: 父容器指定了一个可用大小即SpecSize,View的大小不能大于这个值;它对应于LayoutParams中的 wrap_content 模式。

结论:

子View的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams来共同决定的。

3、measure的重要方法
measure(int widthMeasureSpec, int heightMeasureSpec) 是一个final 方法子类无法重写,会调用onMeasure方法,我们可以在onMeasure方法中处理测量的逻辑。onMeasure(int widthMeasureSpec, int heightMeasureSpec) 在onMeasure方法中处理测量的逻辑。setMeasuredDimension(int measuredWidth, int measuredHeight) 测量的终极方法,测量完成后进行调用,传入测量出来的的宽、高值。

三、layout

public void layout(int l, int t, int r, int b){} 确定View本身的位置。

protected void onLayout(boolean changed, int left, int top, int right, int bottom) { } 确定所有子元素的位置; 父容器的位置确定后,它在onLayout中会遍历所有的子元素并调用其layout方法,在layout方法中会调用onLayout方法。

四、draw

1、将View绘制在屏幕上,遵循如下几步:

1、绘制背景:drawBackground(canvas); 2、绘制自己 : onDraw(canvas); 3、绘制childen :dispatchDraw(canvas); 4、绘制装饰: onDrawForeground(canvas);

2、invalidate()、requestLayout()

invalidate()和requestLayout(),常用于View重绘和更新,其主要区别如下:

invalidate方法只会执行onDraw方法;

requestLayout方法只会执行onMeasure方法和onLayout方法,并不会执行onDraw方法;

所以当我们进行View更新时,若仅View的显示内容发生改变且新显示内容不影响View的大小、位置,则只需调用invalidate方法;若View宽高、位置发生改变且显示内容不变,只需调用requestLayout方法;若两者均发生改变,则需调用两者,按照View的绘制流程,推荐先调用requestLayout方法再调用invalidate方法。

3、invalidate() 和 postInvalidate()

invalidate方法用于UI线程中重新绘制视图 postInvalidate方法用于非UI线程中重新绘制视图,省去使用handler

转载请注明原文地址: https://www.6miu.com/read-2250389.html

最新回复(0)