如何在代码中正确获取Android ImageView的宽度和高度
ImageView 宽高正确获取方案
问题原因
Android View 的渲染需要经过测量(measure)、布局(layout)、**绘制(draw)**三个阶段,直接在页面生命周期早期(如onCreate、onStart)调用width/height属性时,View 还未完成测量和布局流程,系统还未计算出实际尺寸,因此会返回0。当设置wrap_content、match_parent属性时,View 尺寸需要依赖父容器的尺寸计算,更容易出现取值异常,你遇到的空值大概率是属性拼写错误(示例代码中将width拼成了widht),修正拼写即可避免该类空值问题。
通用解决方案
以下方案适配全量 ImageView 使用场景,可以稳定拿到正确尺寸:
方案1:
View.post(最简洁常用)传入的 Runnable 会被加入 View 的消息队列,等到 View 完成测量、布局流程后才会执行,此时取值正确。
binding.image.post { val width = binding.image.width val height = binding.image.height // 执行后续业务逻辑 }方案2:
ViewTreeObserver.OnPreDrawListener(兼容低版本场景)监听 View 绘制前的回调,此时测量已经完成,记得用完要移除监听避免重复触发。
binding.image.viewTreeObserver.addOnPreDrawListener(object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { // 移除当前监听,避免多次回调 binding.image.viewTreeObserver.removeOnPreDrawListener(this) val width = binding.image.width val height = binding.image.height // 执行后续业务逻辑 return true } })方案3:AndroidX KTX 扩展函数(项目引入 KTX 时推荐)
官方已经封装好监听逻辑,无需手动移除回调,写法更简洁。
binding.image.doOnLayout { view -> val width = view.width val height = view.height // 执行后续业务逻辑 }特殊场景:获取 Drawable 原始尺寸
如果你需要的是 ImageView 承载的图片本身的原始尺寸,不受 View 布局属性影响,可以直接取 Drawable 的固有宽高:
binding.image.drawable?.let { drawable -> val originWidth = drawable.intrinsicWidth val originHeight = drawable.intrinsicHeight // 执行后续业务逻辑 }
内容的提问来源于stack exchange,提问作者Nicote Ool
相关产品推荐
相关产品推荐

