共计 1502 个字符,预计需要花费 4 分钟才能阅读完成。
视频:价值 100w+Android 我的项目实战大全:手把手实战,自定义 View
原文:https://juejin.cn/post/6969132819855441934
View 的生命周期
先 onMeasure()测量、再 onLayout()布局、最初 onDraw()绘制。
在 onMeasure()度量时,会先去度量儿子(先走儿子的生命周期),想确认儿子的大小能力确认本人的大小。
自定义 View 分成两类:
- 自定义 View
个别继承自 View,SurfaceView 或其余的 View。
onMeasure()–> onDraw()都会执行,onLayout()看需要
- 自定义 ViewGroup
继承自 ViewGroup 或各种 Layout
onMeasure()–> onLayout()都会执行,onDraw()看需要
自定义 View 蕴含什么
布局:onlayout onmeausre/ Layout:viewGroup
显示:onDraw:view:canvas paint matrix clip rect animation path(贝塞尔)line text 绘制 frameWork:交互:onTouchEvent:组合的 viewGroup
LayoutParams 与 MeasureSpec
LayoutParams
LayoutParams(布局参数),也就是 xml 里定义的
获取
MeasureSpec
MeasureSpec 是一个(32 位)的 int 值,高两位示意父容器对 view 的布局上的限度(Mode),低 30 位示意 view 的 Size
1.unspecified– 无限度
2.exactly — 确定的大小
3.at\_most — 最大不超过
实现流式布局
1. 继承 ViewGroup
2. 自定义 ViewGroup 须要实现 onMeasure()度量和 onLayout()
3. 规范开局,要度量本人的大小得先度量儿子的大小,所以遍历儿子 View,去 view.measure()
4. 儿子的宽高是依据父亲给他的 MeasureSpec 的 Mode + 上本人的 LayoutParams 算进去的,也就是下面的那个表格。如父亲给的是 exactly(确定的大小),儿子又是 android:layout\_width=”10dp”,两个都是确定的,那就是 10dp
5. 取到儿子的宽高
6. 儿子的宽高拿到了,那就是计算每行的宽度(并且取最大行宽度)。计算总的高度
7.for 循环跑完了,这样每个孩子都度量完了,也晓得了最大的宽高,就能够度量本人的宽高了
8. 然而本人的宽高并不只受儿子的影响,还跟父亲给的 Mode 相干
到此 onMeasure()度量完了,接下来开始布局 onLayout()
9. 因为度量的时候,曾经确定了每一行存哪几个 View,把他存到数组里,这样布局的时候简略很多
10. 布局 onLayout()重要的就是确定上下左右。
所谓的上下左右就是间隔父亲总边框的左上角的地位
所以第一个 view 的左就是 0,右就是 左 +view 的宽度。(计算时思考 view 间接的 margin 就行)
第二个 view 就是 第一个 View 的右 + 第二个 view 的左 …. 顺次类推(用掉的宽高)
补充
view.getMeasuredWidth()与 view.getWidth()
取宽高的时候为啥是 view.getMeasuredWidth()。
view.getMeasuredWidth()度量之后这个就有值,然而 view.getWidth()得 view 绘制实现
所以有的时候用 view.getWidth()取值的时候是 0,然而刷新一下或者下一个绘制时又有值了。
view 的 Visibility 别忘了
是不是暗藏的状况得思考