现在的位置: 首页 > 综合 > 正文

详解getWidth和getMeasuredWidth为什么是0

2017年12月02日 ⁄ 综合 ⁄ 共 1447字 ⁄ 字号 评论关闭

首先要知道View的绘制有mesure,layout,draw三个过程

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 :) 
        }
    });

2.添加runnable到view的消息队列 View.post()

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();


抱歉!评论已关闭.