您的位置:首页 > 移动开发 > Android开发

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

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

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


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

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


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

下面给大家提供两种可行的解决方案:

使用 ViewTreeObserver 提供的 Hook 方法。

@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);
// 获取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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: