Android解决在onCreate()中获取View的width、Height为0的方法
16lz
2021-01-24
前言
- 在activity中,经常需要获取view的width和height,但是在onCreate()获取view的width和height会得到0。view.getWidth()和view.getHeight()为0的根本原因是:控件还没有完成绘制。这种情况当我们使用动态布局(使用wrap_content或match_parent)就会出现。
- 一般来讲在Activity.onCreate(…)、onResume()方法中都没有办法获取到View的实际宽高。So,我们必须用一种变通的方法,等到View绘制完成后去获取width和Height。
- 下面有一些可行的解决方案:
1. 监听Draw/Layout事件:ViewTreeObserver
ViewTreeObserver监听很多不同的界面绘制事件。一般来说OnGlobalLayoutListener就是可以让我们获得到view的width和height的地方.下面onGlobalLayout内的代码会在View完成Layout过程后调用。
view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mScrollView.post(new Runnable() { public void run() { view.getHeight(); //height可用了 } }); }});
但是要注意这个方法在每次有些view的Layout发生变化的时候被调用(比如某个View被设置为Invisible),所以在得到你想要的宽高后,记得移除onGlobleLayoutListener:
在 SDK Lvl < 16时使用public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)在 SDK Lvl >= 16时使用public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
2. 将一个runnable添加到Layout队列中:View.post()
这个解决方案是比较好的。简单地说,只要用View.post()一个runnable就可以了。runnable对象中的方法会在View的measure、layout等事件后触发,UI事件队列会按顺序处理事件。在setContentView()被调用后,事件队列中会包含一个要求重新layout的message,所以任何post到队列中的东西都会在Layout发生变化后执行。
view.post(new Runnable() { @Override public void run() { view.getHeight(); //height可用 } });
3. 重写View的onLayout方法
这个方法谨慎使用,一般用在:所要执行的代码应该作为内部逻辑,从而实现高内聚的view模块,否者这个解决方案就显得很耦合、拖拉。
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可用 }};
需要注意的是onLayout方法会被调用很多次,所以要考虑好在这个方法中要做什么,或者在第一次执行后禁用掉代码。
4. 重写Activity的onWindowFocusChanged方法
如果要获取的view的width和height是固定的,那么可以直接使用:
@Overridepublic void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //此处可以正常获取width、height等}
在Activity得到或者失去焦点的时候,就会被调用。Activity初始化完毕准备显示的时候就会回调该方法。所以说,只要想做一些Activity加载完毕就马上触发的事情,都可以在这里执行。
5. 获取固定宽高
如果要获取的view的width和height是固定的,那么可以直接使用:
View.getMeasureWidth()View.getMeasureHeight()
更多相关文章
- Android图像处理之Bitmap类
- [置顶] android 多线程Thread,Runnable,Handler,AsyncTask等之间
- 第25章、OnTouchListener触摸事件(从零开始学Android)
- Android(安卓)ADB 找不到设备的解决方法
- Android(安卓):Kernel Uevent发送(热插拔)事件到用户空间
- 初学Android,数据存储之SharedPreferences(四十一)
- android 预装第三方apk的方法(非system priv-app)
- Android之View基础总结(View的事件体系一)
- Android(安卓)TextView使用HTML处理字体样式、显示图片等