Android控件绘制完成原来是这样的

来源:互联网 发布:伊犁知乎 编辑:程序博客网 时间:2024/06/05 15:41

实际开发中经常会碰到需要获取某个控件的宽度和高度的情况,但是在实际测试中我们在Activity的启动中期函数中废了老大劲了,我们发现是这样的

OnCreate=>>>>>>>>>width==0,height==0 onStart=>>>>>>>>>width==0,height==0onResume=>>>>>>>>>width==0,height==0

这可不就傻眼了,裤子都脱了,你就给我看这个。好吧我们再尝试一下,试一试Activity的那些Hook方法内在什么时候width与height在那个方法内不为0,我们终于有发现了:

OnCreate=>>>>>>>>>width==0,height==0onStart=>>>>>>>>>width==0,height==0onPostCreate=>>>>>>>>>width==0,height==0onResume=>>>>>>>>>width==0,height==0onPostResume=>>>>>>>>>width==0,height==0onAttachedToWindow=>>>>>>>>>width==0,height==0onWindowFocusChanged=>>>>>>>>>width==222,height==58

是不是感觉有种千呼万唤始出来的感觉,原来在onWindowFocusChange()`方法调用的时候完成了控件的绘制。有的哥们肯定要开心了,这问题就解决了,我复写onWindowFocusChanged()方法,在这个方法内是获取控件的宽度和高度就可以了。当然这个方案在解决Activity内的控件获取高度的时候不失为一个不错的方案,代码量少,逻辑清晰。但是,问题又来了,虽然在 onWinodwsFocusChanged() 函数中,可以得到正确的控件尺寸。但这只在 Activity 中奏效,而在 Fragment 中,该方法并不能生效。那我们又该怎么在适当的时候获取控件的宽度和高度呢?
下面给大家提供两种可行的解决方案:

  • 使用 ViewTreeObserver 提供的 Hook 方法。
@Overrideprotected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        hello_world_tv = (TextView)       this.findViewById(R.id.hello_world_tv);        // 获取View的观察者        final ViewTreeObserver observer = hello_world_tv.getViewTreeObserver();        // 给观察者添加布局监听器        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {            @SuppressWarnings("deprecation")            @SuppressLint("NewApi")            @Override            public void onGlobalLayout() {                getWidthAndHeight("onGlobalLayout");                final int version = VERSION.SDK_INT;                /*                 * 移除监听器,避免重复调用                 */                // 判断sdk版本,removeGlobalOnLayoutListener在API 16以后不再使用                if (version >= 16) {                    observer.removeOnGlobalLayoutListener(this);                } else {                    observer.removeGlobalOnLayoutListener(this);                }            }        });    }

该方法在 onGlobalLayout() 方法将在控件完成绘制后调用,因而可以得到正确地结果。该方法在 Fragment 中,也可以使用。
- 使用 View 的 post() 方法

    @Override    protected void onCreate(final Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        hello_world_tv = (TextView) this.findViewById(R.id.hello_world_tv);        hello_world_tv.post(new Runnable() {            @Override            public void run() {                getWidthAndHeight("post");            }        });    }

这种方法是比较简单并可靠的做法
经过这么一番折腾,我们可以得出android中控件的高度和宽度需要绘制完成后才能获取到。那么获取的方法有:
1.Acyivity内通过复写onWinodwsFocusChanged()方法,在这个方法内去获取控件的相关属性(Fragment内不适用)
2.最优雅的做法是调用View的post()方法
3.使用 ViewTreeObserver 注册 OnGlobalLayoutListener

0 0
原创粉丝点击