其他
这样学习View的测量算法,真的很有趣哦
View 指定高度为固定值时,其中负数等同于0,实际高度为指定高度(对应①、②、⑥、⑦、⑧、⑪、⑫、⑬)。但有一个特例,就是父 View 指定高度为负数,子 View 指定高度为非负数,此时父 View 实际高度不是为0,而是为子 View 实际高度(对应③)。 View 指定高度为 wrap_content,如果其子 View 高度为固定值(其中负数等同于0),则实际高度为子 View 实际高度(对应④、⑨、⑭),否则结果同 match_parent,为父 View 实际高度(对应⑯、⑰、⑱、⑲、⑳、㉔)。 View 指定高度为 match_parent,实际高度为父 View 实际高度(对应⑤、⑩、⑮、⑳、㉑、㉒、㉓、㉔、㉕)。
父 View 指定高 -300 px,子 View 指定高 100 px,父 View 实际高度为什么是 100 px 不是 0 px? 父控件指定高度为 wrap_content ,子控件指定高度为 match_parent 如何计算?为什么 View 和 FrameLayout 等常用控件不一样? 子控件为 View,为什么指定高度为 match_parent 和 wrap_content 时结果都一样?
测量模式为 UNSPECIFIED 时高度为 size 其他情况高度为 specSize
测量规格为 AT_MOST,高度为 size 和 specSize 的最小值 测量规格为 EXACTLY,高度为 specSize 测量规格为 UNSPECIFIED,高度为 size
指定了非负值,则直接为该值 指定为 match_parent,则为父控件测量规格 指定为 wrap_content,除 EXACTLY 时修正为 AT_MOST,其他同父控件测量规格 其他数对应默认测量规格(0,UNSPECIFIED)
View 则调用 View.getDefaultSize() 获取实际高度为父控件指定的 leftSpecSize,也就会出现和屏幕等高的结果。 其他常用控件则调用 View.resolveSizeAndState() ,在 AT_MOST 模式下返回最小高度。
符合复现 UNSPECIFIED 这种测量模式,设置为小于 -2 的数即可做到,能够测试覆盖自定义控件逻辑的鲁棒性。 自由设置若干子控件和自适应高度子控件一样高,曾经有个需求就是服务端下发文案和图片 url,要求达到图片作为文案的背景效果。因为 TextView 高度是自适应,需要将 ImageView 和 TextView 设置成一样高。最佳实践就是重写父控件 View.onMeasure() 方法,TextView 计算出高度后直接设置 ImageView 高度 (文本控件高度,EXACTLY)即可。 继承 View 自定义控件时,记得重写 View.onMeasure() 方法处理 wrap_content 和 match_parent 默认一样效果的反常识情况。 方便其他自定义控件实现优雅交互,和技术大牛过几招。