getMeasuredWidth和getMeasuredHeight在mesure过程结束后就可以获取到,他的值是由测量过程中setMeasuredDimension设置的
getWidth方法和geiHeight方法在layout过程结束后才能获取到,他的值是右边的减去左边的值得到的
再回过头来说说为什么得到的是0,就是因为我们在调用的时候View根本没用进行绘制相应的函数没有调用。
以上知识来自郭霖大侠的博客
Android视图绘制流程完全解析,带你一步步深入了解View(二)
知道了原因再来说说解决方法,我简单归纳一下,具体大家可以去看看这篇文章
点击打开链接
1.监听View的Draw/Layout事件:ViewTreeObserver
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Ensure you call it only once :
yourView.getViewTreeObserver().removeGlobalOnLayoutListener(this);//得到后取消监听
// Here you can get the size :)
}
});
The UI event queue will process events in order. After setContentView() is invoked, the event queue will contain a message asking for a relayout, so anything you post to the queue will happen after the layout pass
UI事件队列会按顺序执行,当你调用setcontentView后,消息队列包含了了一个请求重新布局的消息,所以你添加的消息会在之后执行。
final View view=//smth;
...
view.post(new Runnable() {
@Override
public void run() {
view.getHeight(); //height is ready
}
});
相比ViewTreeObserver来说这种方法只会执行一次也不用取消监听,代码更精简.
3.重写view的onLayout方法
view = new View(this) {
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
view.getHeight(); //height is ready
}
};
注意这个方法会被调用很多次,写代码的时候小心或者只在第一次有效
4.重写onSizeChange方法
5.获取getMeasuredWidth之前先mesure一下
myImage.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
int height = myImage.getMeasuredHeight();
int width = myImage.getMeasuredWidth();