自定义View的一些流程

可将整个绘制过程分为三部分:Measure - Layout - Draw  自定义ViewGrop  onMeasure() onLayout()    自定义View则  onMeasure()   onDraw()

自定义View的四个构造器

构造函数参数说明:

Context - 上下文;

AttributeSet - xml文件中的属性;

int defStyleAttr - Theme中的默认样式;

int defStyleResource - defStyleAttr未使用(为0,或者未匹配到),则应用于View的默认样式;

R.style中系统为view定义了很多默认主题Theme,主题中有对某些属性的默认赋值。

Measure 过程(自定义ViewGroup)

1. 先测量子视图再测量父视图


父视图会调用子视图的onMeasure(widthMeasureSpec ,heightmeasurespec) 子视图会调用子视图的onMeasure递归调用直到没有子视图结束调用.自定义View中重写的OnMeasure参数来自于父布局。

测量子视图通过getChildCound  获得子View个数逐个测量调用ChildView.setMeasure(childwidthMeasureSpec,childhetihtMeasureSpec),这个参数的来源不仅仅是LayoutParmes. 通过提供的getChildWidthMeasureSpec(父视图的Spec,padding,childview大小)计算得到

我们知道子视图的宽度高度在xml分为三种模式一种是确定大小的dp一种是warpcontent 一种是不确定的。通过child.getLayoutParmes获取每一个子视图的参数最后测量父视图通过setMeasuredDimension(width,height)设置值并保存里面的值如果父布局是Extially 从父布局的widthMeasureSpec 获取,否则就通过子view累加获得

Layout 过程

1. 在Layout过程中,子视图会调用getMeasuredWidth()和getMeasuredHeight()方法获取到measure过程得到mMeasuredWidth和mMeasuredHeight,作为自己的width和height。然后调用每一个子视图的layout(),来确定每个子视图在父视图中的位置。

layout(l ,r,t,b)涉及到view的坐标系 layout也是z子View先布局然后父view再布局.子view的left  right  bottom top都是通过子视图getMeasureWidth算出来 。getwidth()方法是onLayout之后才能调用,   getmeasurewidth()则是通过测量之后setMeasureDimension()设置保存的

Draw 过程

1. dispatchDraw()发起对子视图的绘制,在View中默认为空实现,ViewGroup复写了dispatchDraw()来对其子视图进行绘制。

tip1.不要将初始化参数放到OnMeasure中因为OnMeasure多次调用容易内存抖动

tip2.自定义ViewGroup的 时候 整体的宽高会加上padding  子视图会去掉padding

tip3.测量的时候要判断子视图是否可见

tip4,onLyout的时候要考虑gravity

你可能感兴趣的:(自定义View的一些流程)