ImageView.getWidth返回0的问题

我们在为Android的ImageView控件添加动画或者根据屏幕宽高进行动态调整图片的宽高的时候,经常会用到ImageView.getWidth()来获取图片的宽高,然而遗憾的是:很多时候ImageView.getWidth()得到的结果都是0

Android View的绘制流程

基本的绘制流程大体上分为如下三个阶段:

1
onMeasure()-onLayout()-onDraw()

关于三个阶段的具体细节网上有很多讲解,简单来说:onMeasure()阶段做的主要工作就是根据父视图计算View的宽高,onLayout()阶段就是根据onMeasure()阶段计算出来的宽高,对View进行布局的摆放,根据父视图确定View的位置,onDraw()顾名思义就是在准备工作都完成,计算好宽高和位置之后进行开始真正的视图绘制工作了,一般是创建一个Canvas画布,然后在其上面draw真正的view视图,当onDraw完成之后,我们就看到了显示到手机上的各个View控件。

ImageView.getWidth()返回0的原因

view还没有完成onMeasure或者onLayout

很多时候我们在onCreate或者onResume方法内调用ImageView.getWidth()的时候,由于布局视图太复杂,特别是View的宽高是相对值的时候(比如wrap_content或者match_parent),视图的onMeasure()和onLayout()方法并没有真正完成,也就是说并没有计算出视图的宽高,所以这个时候调用ImageView.getWidth()肯定会返回0

view从GONE状态到Visibilty还在渲染过程中

还有就是我们如果调用View.setViewbility(View.GONE)方法,那么View的宽和高也会再次被设置为0,那么通过setVisibility(View.Visibility)之后立即调通ImageView.getWidth(),也会返回0,因为setVisibility之后,控件要重新计算大小进行绘制,在计算大小完成之前调用getWidth()一样会返回0。

##解决办法

附上测试的几个回调方法的执行流程

1
2
3
Activity.oncreate()→Activity.onResume()→TestImageView.onMeasure()
→TestImageView.onLayout()→onGlobalLayoutListener()
→Activity.onWidnowFocusChanged()→...→TextImageView.onDraw()

省略的…部分可能会重复调用onMeasure-onLayout-onGlobalLayoutListener