前言
我们知道, 在Activity
的onCreate
中通过width
和height
方法是通常是无法获取到控件的宽高的
因为控件还未测量完毕
如果想要获取到值, 那么有以下几种方式可选
第一种 获取前调用一次measure
方法
示例如下:
1 | int width = View.MeasureSpec.makeMeasureSpec(0, |
第二种 使用ViewTreeObserver. OnPreDrawListener
进行绘制前事件监听
示例如下:
1 | view.getViewTreeObserver().addOnPreDrawListener( |
该方法会被调用多次,因此获取到视图的宽度和高度后要移除该监听事件
第三种 使用ViewTreeObserver. OnGlobalLayoutListener
在布局发生改变或者某个视图的可视状态发生改变时调用该事件
示例如下:
1 | view.getViewTreeObserver().addOnGlobalLayoutListener( |
该方法会被多次调用,因此需要在获取到视图的宽度和高度后执行 remove 方法移除该监听事件。
第四种 使用View.OnLayoutChangeListener
在视图的 layout 改变时调用该事件, API>=11
才能使用
示例如下:
1 | view.addOnLayoutChangeListener( |
该方法同样会被多次调用,因此需要在获取到视图的宽度和高度后执行 remove 方法移除该监听事件。
第五种 View.post() 方法
方法会在 View 的 measure、layout 等事件完成后触发
示例如下:
1 | view.post(new Runnable() { |
该方法只会执行一次,且逻辑简单,建议使用
第六种 重写 View 的 onSizeChanged 方法
在视图的大小发生改变时调用该方法,会被多次调用,因此获取到宽度和高度后需要考虑禁用掉代码
示例如下:
1 | @Override |
该实现方法需要继承 View,且多次被调用,不建议使用
第七种 重写 View 的 onLayout 方法
示例如下:
1 | @Override |
该实现方法需要继承 View,且多次被调用,不建议使用
实际场景
目前有个业务需求, 我需要在addView
之后获取到被add
子控件的宽高, 此时最好的方法就是使用View.post
, 如下:
本文为作者原创转载时请注明出处 谢谢