zoukankan      html  css  js  c++  java
  • Android 开发 Activity里获取View的宽度和高度 转载

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

    前言:

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

    疑问解答:

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

    解决方案:

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

    onWindowFocusChanged方法中获取:

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

    Activity的onWindowFocusChanged中获取view的宽度和高度
     @Override
        public void onWindowFocusChanged(boolean hasWindowFocus) {
            super.onWindowFocusChanged(hasWindowFocus);
            if(hasWindowFocus){
                int width = view.getMeasuredWidth();
                int height = view.getMeasuredHeight();
            }
        }

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

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

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

    Activity通过mView.post方法获取

       mView.post(new Runnable() {
                @Override
                public void run() {
                    int width = mView.getMeasuredWidth();
                    int height = mView.getMeasuredHeight();
                }
            });

    通过ViewTreeObserver获取:

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

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

     ViewTreeObserver observer = mView.getViewTreeObserver();
            observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    mView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    int width = mView.getMeasuredWidth();
                    int height = mView.getMeasuredHeight();
                }
            });

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

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

    int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.EXACTLY);
    
    int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.EXACTLY);
    
    view.measure(width,height);
    
    int height=view.getMeasuredHeight();
    
    int width=view.getMeasuredWidth();


    View的LayoutParams参数为wrap_content:

    int width =View.MeasureSpec.makeMeasureSpec((1<<30)-1,View.MeasureSpec.AT_MOST);
    
    int height =View.MeasureSpec.makeMeasureSpec((1<<30)-1,View.MeasureSpec.AT_MOST);
    
    view.measure(width,height);
    
    int height=view.getMeasuredHeight();
    
    int width=view.getMeasuredWidth(); 
  • 相关阅读:
    联合主键有什么用?
    在Spring Boot中使用数据库事务
    Integer.valueOf
    Linux上安装Zookeeper以及一些注意事项
    一个开源的会议管理系统,适合初学者练手(老司机请忽略)
    一个开源的会议管理系统,适合初学者练手(老司机请忽略)
    IntelliJ IDEA中创建Web聚合项目(Maven多模块项目)
    从高考到程序员之毕业流水帐
    Nginx+Tomcat搭建集群,Spring Session+Redis实现Session共享
    Shiro中的授权问题(二)
  • 原文地址:https://www.cnblogs.com/guanxinjing/p/10499768.html
Copyright © 2011-2022 走看看