原文地址:https://blog.csdn.net/chenbaige/article/details/77991594

前言:

可能很多情况下,我们都会有在activity中获取view 的尺寸大小(宽度和高度)的需求。面对这种情况,很多同学立马反应:这么简单的问题,还用你说?你是不是傻。。然后立马写下getWidth()、getHeight()等方法,洋洋得意的就走了。然而事实就是这样的吗?实践证明,我们这样是获取不到View的宽度和高度大小的,可能很多同学又会纳闷了,这是为什么呢?一直不都是这样获取大小的嘛!

疑问解答:

实际情况下,View的measure过程和Activity的生命周期方法不是同步执行的,因此无法保证Activity在执行完某个生命周期方法时View已经测量完毕了,这种情况下,获取到的尺寸大小就是0。因此,在很多情况下,我们正在为我们机智而得意时,事实却让我们大跌眼镜,甚是尴尬。

解决方案:

接下来我们介绍四种方式去正确的获取View的尺寸大小。

onWindowFocusChanged方法中获取:

onWindowFocusChanged方法执行时代表View已经初始化完毕了,宽度和高度已经测量完毕并且最终确认好了,这时我们可以放心的在这里去获取View 的宽度和高度。代码如下:

  1. ActivityonWindowFocusChanged中获取view的宽度和高度
  2. @Override
  3. public void onWindowFocusChanged(boolean hasWindowFocus) {
  4. super.onWindowFocusChanged(hasWindowFocus);
  5. if(hasWindowFocus){
  6. int width = view.getMeasuredWidth();
  7. int height = view.getMeasuredHeight();
  8. }
  9. }

注意:虽然使用很方便,但在使用这个方法时需要特别注意:onWindowFocusChanged会执行多次,在Activity获取焦点和失去焦点时都会被调用一次。即在onPause和onResume方法被执行时被反复调用。

View.post(new Runnable())方法中获取:

通过View.post方法把Runnable对象放到消息队列的末尾,当执行到这个runable方法的时候,View所有的初始化测量方法说明都已经执行完毕了。因此在这里获取的时候就是测量后的真实值。代码如下:

Activity通过mView.post方法获取

  1. mView.post(new Runnable() {
  2. @Override
  3. public void run() {
  4. int width = mView.getMeasuredWidth();
  5. int height = mView.getMeasuredHeight();
  6. }
  7. });

通过ViewTreeObserver获取:

当View树的状态发生改变或者View树内部View的可见性发生改变的时候,onGlobalLayout将会被回调。注意:伴随着View树的状态改变,onGlobalLayout会被调用多次。实现如下:

在Activity生命周期方法中通过ViewTreeObserver获取

  1. ViewTreeObserver observer = mView.getViewTreeObserver();
  2. observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
  3. @Override
  4. public void onGlobalLayout() {
  5. mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
  6. int width = mView.getMeasuredWidth();
  7. int height = mView.getMeasuredHeight();
  8. }
  9. });

手动调用View的measure方法后获取:

手动调用measure后,View会调用onMeasure方法对View发起测量,测量完后,就可以获取测量后的宽度和高度了。但是要对LayoutParams的参数分情况处理才能得到具体的参数值:
View的LayoutParams参数为match_parent:这种情况下无法获取到具体宽高值,因为当View的测量模式为match_parent时,宽高值是取父容器的剩余空间大小作为它自己的宽高。而这时无法获取到父容器的尺寸大小,因此获取会失败。
View的LayoutParams参数为具体值:

  1. int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.EXACTLY);
  2.  
  3. int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.EXACTLY);
  4.  
  5. view.measure(width,height);
  6.  
  7. int height=view.getMeasuredHeight();
  8.  
  9. int width=view.getMeasuredWidth();

View的LayoutParams参数为wrap_content:

  1. int width =View.MeasureSpec.makeMeasureSpec((1<<30)-1,View.MeasureSpec.AT_MOST);
  2.  
  3. int height =View.MeasureSpec.makeMeasureSpec((1<<30)-1,View.MeasureSpec.AT_MOST);
  4.  
  5. view.measure(width,height);
  6.  
  7. int height=view.getMeasuredHeight();
  8.  
  9. int width=view.getMeasuredWidth();

Android 开发 Activity里获取View的宽度和高度 转载的更多相关文章

  1. HackThirteen 在onCreate()方法中获取View的宽度和高度

    1.概要:     Android源代码中很多模块都使用了post()方法,深入理解框架曾运行机制对于避开类似于本例中的小陷阱是很重要的 2.问题提出:     如果开发一些依赖于UI控件的宽和高的功 ...

  2. Activity中获取view的高度和宽度为0的原因以及解决方案

    在activity中可以调用View.getWidth.View.getHeight().View.getMeasuredWidth() .View.getgetMeasuredHeight()来获得 ...

  3. Android开发艺术探索笔记——View(二)

    Android开发艺术探索笔记--View(二) View的事件分发机制 学习资料: 1.Understanding Android Input Touch Events System Framewo ...

  4. Android开发艺术探索笔记—— View(一)

    Android开发艺术探索笔记 --View(一) View的基础知识 什么是View View是Android中所有控件的基类.是一种界面层控件的抽象. View的位置参数 参数名 获取方式 含义 ...

  5. Android开发——Activity生命周期

    Android开发--Activity生命周期 Activity作为四大组件之首,也是使用最频繁的一种组件.本文将主要讲解Activity生命周期,包括正常情况下的Activity生命周期和异常情况下 ...

  6. android应用程序中获取view的位置

    我们重点在获取view的y坐标,你懂的... 依次介绍以下四个方法: 1.getLocationInWindow int[] position = new int[2]; textview.getLo ...

  7. Android开发 ---Activity的7种运行状态

     Android开发 ---Activity的7种运行状态 创建 --> 启动 --> 运行 -->  暂停 --> 停止 --> 销毁 重启 操作图解: 1.MainA ...

  8. android开发中fragment获取context

    在用到fragment时无法使用.this来指定当前context内容,android开发中fragment获取context,可以使用getActivity().getApplicationCont ...

  9. android之获取屏幕的宽度和高度

    获取屏幕的宽度和高度: 方法一: //获取屏幕的宽度 public static int getScreenWidth(Context context) { WindowManager manager ...

随机推荐

  1. Matlab 将RGB 图像转换成YCrCb图像

    >> im = imread('trees.jpg');>> imshow(im)>> ycrcb_trees = rgb2ycbcr(im);>> f ...

  2. mysql 两张表的数据设置主外健关联删除

    image_group 主表 image 副表 alter table image add constraint fk_group_idforeign key (group_id)references ...

  3. js判断页面在pc端打开还是移动端打开

    js判断页面在pc端打开还是移动端打开,分别跳转不同的index.html window.addEventListener('load', function() { // true为手机,false为 ...

  4. 使用CMake生成解决方案后构建INSTALL报错

    错误 1 error MSB3073: 命令“setlocal"D:\Program Files\CMake\bin\cmake.exe" -DBUILD_TYPE=Debug - ...

  5. java项目---用java实现简单TCP服务器监听(3星)

    ---------------------------------------------服务端----------------------------------------------- 1 pa ...

  6. 学习笔记TF055:TensorFlow神经网络简单实现一元二次函数

    TensorFlow运行方式.加载数据.定义超参数,构建网络,训练模型,评估模型.预测. 构造一个满足一元二次函数y=ax^2+b原始数据,构建最简单神经网络,包含输入层.隐藏层.输出层.Tensor ...

  7. 经典问题----最短路径(Floyd弗洛伊德算法)(HDU2066)

    问题简介: 给定T条路,S个起点,D个终点,求最短的起点到终点的距离. 思路简介: 弗洛伊德算法即先以a作为中转点,再以a.b作为中转点,直到所有的点都做过中转点,求得所有点到其他点的最短路径,Flo ...

  8. InsertSort

    #include <bits/stdc++.h> using namespace std; #define MAXSIZE 200000 typedef int KeyType; type ...

  9. jquery案例

    调用js成员 <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>& ...

  10. C#利用首尾時間計算中間時間差

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...