一般我们在Activity中会用getWidth()方法,去获得view的宽度,但是不论在Oncreate()中,还是onResume()中,获得的值都是0
出现这种原因是因为,我们在调用getWidth()时,View还没执行完OnMeasure()方法。得到的自然就是0
1.最常用的:View.post()
利用handler的通信机制,当view layout处理完成时,自动发送消息,通知UI线程,这样就可以获得View的宽高属性
view.post(new Runnable() {
@Override
public void run() {
int width = view.getWidth();
}
});
2.onLayout()
利用绘图的生命周期,在onLayout() 方法获取宽高值
tv = new TextView(this) { @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); int a = tv.getWidth(); } };
3.addOnGlobalLayoutListener
ViewTreeObserver,视图树的观察者,可以监听 View 的全局变化事件
注意:使用时需要注意及时移除该事件的监听,避免后续每一次发生全局 View 变化均触发该事件,影响性能。这里用的是 OnGlobalLayoutListener,移除监听时注意 API 的版本兼容处理。
tv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if (Build.VERSION.SDK_INT >= 16) { tv.getViewTreeObserver().removeOnGlobalLayoutListener(this); }else { tv.getViewTreeObserver().removeGlobalOnLayoutListener(this); } int width = tv.getWidth(); Log.e("getViewTreeObserver",String.valueOf(width)); } });
4.addOnPreDrawListener
同上
tv.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { tv.getViewTreeObserver().removeOnPreDrawListener(this); int width = tv.getWidth(); Log.e("addOnPreDrawListener",String.valueOf(width)); return false; } });
5.addOnLayoutChangeListener
监听 View 的 onLayout() 绘制过程,一旦 layout 触发变化,立即回调 onLayoutChange
方法。注意,用完也要注意调用 remove 方法移除监听事件。
tv.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { tv.removeOnLayoutChangeListener(this); int width = tv.getWidth(); Log.e("LayoutChangeListener",String.valueOf(width)); } });