Android/Kotlin:视图在生命周期中何时初始化?如何获取Button尺寸?
解决Android生命周期早期无法获取View尺寸的问题
哈哈,这个坑我刚入行的时候踩过好几次!Android里View的绘制是异步的,onCreate、onStart、onResume这些生命周期方法执行时,你的Button还没走完**measure(测量)和layout(布局)**流程,所以拿不到真实的宽高很正常。给你几个实用的解决办法:
方法1:使用View.post()(最推荐)
View的post()方法会把Runnable放到View的消息队列里,等到View完成布局后再执行,代码简洁还不用手动清理监听:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.post { // 这里可以安全获取宽高 val btnWidth = button.width val btnHeight = button.height servOffset = // 根据尺寸计算你的偏移量 } }
方法2:监听ViewTreeObserver的全局布局事件
通过ViewTreeObserver监听整个View树的布局完成事件,触发后就能拿到View的真实尺寸,记得要移除监听避免重复回调:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val observer = button.viewTreeObserver observer.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { override fun onGlobalLayout() { // 必须移除监听,否则会多次触发 if (observer.isAlive) { observer.removeOnGlobalLayoutListener(this) } // 现在获取尺寸 val btnWidth = button.width val btnHeight = button.height servOffset = // 计算逻辑 } }) }
方法3:重写View的onSizeChanged(自定义View场景)
如果是你自己的自定义View(比如自定义Button),可以直接重写onSizeChanged方法,这里会在View尺寸变化时被调用:
class CustomButton(context: Context, attrs: AttributeSet?) : Button(context, attrs) { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { super.onSizeChanged(w, h, oldw, oldh) // w和h就是当前View的宽高 // 可以通过接口回调把尺寸传给Activity处理 } }
补充说明
Android的View绘制流程是:measure(确定View的测量宽高)→ layout(确定View的最终位置和真实宽高)→ draw(绘制到屏幕)。onCreate等早期生命周期方法只完成了布局的加载,还没执行到measure和layout,所以此时width/height返回的都是0。
内容的提问来源于stack exchange,提问作者Aquaball
相关产品推荐
相关产品推荐

