美文网首页
View的基础知识(一)

View的基础知识(一)

作者: 1dot4 | 来源:发表于2018-04-19 11:46 被阅读14次

    1、View的getWidth() 和 getMeasuredWidth()有什么区别?

    2、如何在onCreate中拿到View的宽度和高度?

    一、 View的getWidth() 和 getMeasuredWidth()有什么区别?

    getWidth()是最终宽度,getMeasuredWidth()是测量宽度。
    两方法严格来说是有区别的,先看下getWidth()源码

    public final int getWidth(){return mRight-mLeft;}
    

    mLeft、mRight、mTop、mBottom:View的位置坐标相对于父view的坐标

    进入正题:在View的默认实现中,View的测量宽高和最终宽高是相等的,只不过测量宽/高形成于View的measure过程,而最终宽/高形成于View的layout过程,即两者的赋值时机不同,测量宽/高的赋值时机稍微早些。

    因此,在日常开发中,我们可以认为View的测量宽/高和最终宽/高是相等的,在某些特殊的情况下是不相等,比如重写了onLayout方法。

    二、如何在onCreate中拿到View的宽度和高度?

    在OnCreate、onStart、onResume中均无法正确的拿到某一个View的宽高,这是因为View的measure过程和Activity的生命周期方法不同步,因此无法保证Activity执行了OnCreate、onStart、onResume时某个View已经测量完毕了,如果还没测量完毕,那么拿到的宽高就是0。

    常用的解决方案有三种。

    • 1 、Activity/View#onWindowFocusChanged

    onWindowFocusChanged这个方法的含义是:View已经初始化完毕了,宽/高已经准备好了。需要注意的是,onWindowFocusChanged会被调用多次,当Activity的窗口获取焦点和市区焦点的时候均会被调用一次。具体来说,如果频繁的进行onResume和onPause,那么onWindowFocusChanged也会被频繁的调用。典型的代码如下:

    public  void onWindowFocusChanged(boolean hasFocus){
        
        super.onWindowFocusChanged(hasFous);
        
        if(hasFocus){
            int width =view.getMeasuredWidth();
            int height=view.getMeasuredHeight();
        }
    }
    
    • 2、 view.post(runnable)

    通过post将一个runnable投递到信息队列的尾部,然后等Looper调用此runnable的时候,View也初始化完成了。典型的代码如下:

    protected void onStart(){
        super.onStart();
        
        view.post(new Runnable(){
            
            @Override public voiud run(){
                int width =view.getMeasuredWidth();
                int height=view.getMeasuredHeight();
            }
        
        });
    }
    
    
    • 3、ViewTreeObserver

    使用ViewTreeObserver的众多回调可以完成这个功能,比如使用OnGlobalLayoutListener这个接口,当View树的状态改变或View树内部的View的可见性改变时,onGlobalLayout方法将被回调,因此这是获取View宽、高的好时机。需要注意的是,伴随着View树的改变等,onGlobalLayout会被调用多次。

    protected void onStart(){
        super.onStart();
        
        ViwwTreeOberver observer=view.getViewTreeObserver();
        
        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
            
            @SuppressWarnings("desprecation")
            @Override
            public void onGlobalLayout(){
                view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                int width =view.getMeasuredWidth();
                int height=view.getMeasuredHeight();
            }
        
        });
    
    
    }
    
    

    相关文章

      网友评论

          本文标题:View的基础知识(一)

          本文链接:https://www.haomeiwen.com/subject/uvfwkftx.html