测量View的宽高,避免为零

https://juejin.im/post/58e4397a44d904006d275eeb

addOnGlobalLayoutListener

view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (Build.VERSION.SDK_INT >= 16) {
            view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }else {
            view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
        int width = view.getWidth();
    }
});

ViewTreeObserver,顾名思义,视图树的观察者,可以监听 View 的全局变化事件。比如,layout 变化,draw 事件等。可以阅读源码了解更多事件。
注意:使用时需要注意及时移除该事件的监听,避免后续每一次发生全局 View 变化均触发该事件,影响性能。这里用的是 OnGlobalLayoutListener,移除监听时注意 API 的版本兼容处理。

addOnPreDrawListener

view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    @Override
    public boolean onPreDraw() {
        view.getViewTreeObserver().removeOnPreDrawListener(this);
        int width = view.getWidth();
        return false;
    }
});

这里同样是利用 ViewTreeObserver 观察者类,只不过这里监听的是 draw 事件。

view.post()

view.post(new Runnable() {
    @Override
    public void run() {
        int width = view.getWidth();
    }
});

利用 Handler 通信机制,添加一个 Runnable 到 message queue 中,当 view layout 处理完成时,自动发送消息,通知 UI 线程。借此机制,巧妙获取 View 的宽高属性。代码简洁,使用简单,相比 ViewTreeObserver 监听处理,还不需要手动移除观察者监听事件。

你可能感兴趣的:(View)