Activity启动过程中获取控件宽高的方式
2016-09-02 17:20
239 查看
问题: 为什么在activity的生命周期中获取不到控件的宽高??
解答: Activity的启动流程和Activity的布局文件加载绘制流程,其实没有相关的关系的,其实两个异步的加载流程,这样我们在Activity的onCreate和onResume方法调用textView.getHeight或者是textView.getWidth方法的时候,其组件并没有执行完绘制流程,因此此时获取到的组件的宽高都是默认的0,也就是无法获取组件的宽和高。
获取控件宽高的方法
1、重写Activity的onWindowFocusChanged方法:
缺点:当window每次获取到焦点时,都会执行此逻辑,必须要做一些判断。
2、为组件添加OnGlobalLayoutListener事件监听:
备注:
a. onGlobalLayout方法会在Activity的组件执行完onLayout方法之后执行;
b. 这里有个ViewTreeObserver对象,这是一个注册监听视图树的观察者;
c. 获取高度之后,要移除GlobalLayoutListener监听器。
3、为组件添加OnPreDrawListener事件监听:
备注:onPreDraw方法会在Activity的组件执行onDraw方法之前执行。
4、使用View.post方法获取组件的宽高:
备注:这里的view的post方法底层使用的是Android的异步消息机制,消息的执行在MainActivity主进程Loop执行之后。
参考资料:http://blog.csdn.net/qq_23547831/article/details/51764304
解答: Activity的启动流程和Activity的布局文件加载绘制流程,其实没有相关的关系的,其实两个异步的加载流程,这样我们在Activity的onCreate和onResume方法调用textView.getHeight或者是textView.getWidth方法的时候,其组件并没有执行完绘制流程,因此此时获取到的组件的宽高都是默认的0,也就是无法获取组件的宽和高。
获取控件宽高的方法
1、重写Activity的onWindowFocusChanged方法:
/** * 重写Acitivty的onWindowFocusChanged方法 */ @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); /** * 当hasFocus为true的时候,说明Activity的Window对象已经获取焦点,进而Activity界面已经加载绘制完成 */ if (hasFocus) { int widht = titleText.getWidth(); int height = titleText.getHeight(); } }
缺点:当window每次获取到焦点时,都会执行此逻辑,必须要做一些判断。
2、为组件添加OnGlobalLayoutListener事件监听:
/** * 为Activity的布局文件添加OnGlobalLayoutListener事件监听,当回调到onGlobalLayout方法的时候我们通过getMeasureHeight和getMeasuredWidth方法可以获取到组件的宽和高 */ private void initOnLayoutListener() { final ViewTreeObserver viewTreeObserver = this.getWindow().getDecorView().getViewTreeObserver(); viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { int height = titleText.getMeasuredHeight(); int width = titleText.getMeasuredWidth(); // 移除GlobalLayoutListener监听 MainActivity.this.getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); }
备注:
a. onGlobalLayout方法会在Activity的组件执行完onLayout方法之后执行;
b. 这里有个ViewTreeObserver对象,这是一个注册监听视图树的观察者;
c. 获取高度之后,要移除GlobalLayoutListener监听器。
3、为组件添加OnPreDrawListener事件监听:
/** * 初始化viewTreeObserver事件监听,重写OnPreDrawListener获取组件高度 */ private void initOnPreDrawListener() { final ViewTreeObserver viewTreeObserver = this.getWindow().getDecorView().getViewTreeObserver(); viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { int height = titleText.getMeasuredHeight(); int width = titleText.getMeasuredWidth(); // 移除OnPreDrawListener事件监听 MainActivity.this.getWindow().getDecorView().getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); }
备注:onPreDraw方法会在Activity的组件执行onDraw方法之前执行。
4、使用View.post方法获取组件的宽高:
/** * 使用View的post方法获取组件的宽度和高度 */ private void initViewHandler() { titleText.post(new Runnable() { @Override public void run() { int width = titleText.getWidth(); int height = titleText.getHeight(); } }); }
备注:这里的view的post方法底层使用的是Android的异步消息机制,消息的执行在MainActivity主进程Loop执行之后。
参考资料:http://blog.csdn.net/qq_23547831/article/details/51764304
相关文章推荐
- github项目解析(八)-->Activity启动过程中获取组件宽高的三种方式
- android developer tips---干掉adb侵入者命令和activity中获取控件宽高方法
- 动态获取控件宽高的四种方式
- 避免Activity启动时某个控件马上获取焦点(如EditText/Gallery等)
- 在activity中加载fragment的两个方式以及获取fragment中的控件的方式
- 避免Activity启动时某个控件马上获取焦点(如EditText/Gallery等)
- 在Activity的onCreate方法中获取控件宽高的N种方法
- activity中如何获取service的运行状态? 使用startservice方式启动
- 【转】获取Activity启动时间的三种方式
- Android启动过程 && Activity生命周期 && Activity开机自启动 && this与getBaseContext && Activity的singleTask类型
- android Activity 启动时不获取焦点
- Android应用程序的Activity启动过程简要介绍和学习计划
- 老罗的Android之旅——Android应用程序的Activity启动过程简要介绍和学习计划
- 我搭建基于XTI_D902-B-V平台以NFS文件系统的方式启动Android的过程
- 浅谈Activity几种不同的启动方式
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Android FrameWork——Activity启动过程详解
- [转]activity的启动方式(launch mode)
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- Coolite控件 客户端JavaScript获取值的方式