在android开发中,我们经常会需要去获取一个view的宽度和高度,如果activity页面已经绘制完毕,我们可以利用view.getWidth()或是view.getHeiht()来获取view的宽和高,但如果是在activity的oncreate()和onResume()方法中用这两个方法,它们获取到的结果都是0,因为在oncreate()时,界面处于不可见状态,内存加载组件还没有绘制出来,而在onResume()中,界面还没有显示出来,所以获取不到值。那么如何在这两个activity的生命周期中获取宽和高呢,有以下几种方法
一、测量法 最早的用法
int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
view.measure(width,height);
int height=view.getMeasuredHeight();
int width=view.getMeasuredWidth();
如此即可
二、组件绘制之前的监听
ViewTreeObserver vto =view.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public booleanonPreDraw() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
}
三、增加整体布局监听,xlistView中用的就是这种方式
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this); // 记得移出监听,避免内存泄漏
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
}
});
四、延迟加载 后来想到的
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
// int height =view.getWidth(); // 两种获取宽高的方式都行
// int width =view.getHeight();
}
},10);
或者 现在用的最多的
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
// int height =view.getWidth(); / 两种获取宽高的方式都行
// int width =view.getHeight();
}
一、测量法 最早的用法
int width =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
int height =View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
view.measure(width,height);
int height=view.getMeasuredHeight();
int width=view.getMeasuredWidth();
如此即可
二、组件绘制之前的监听
ViewTreeObserver vto =view.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public booleanonPreDraw() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
}
三、增加整体布局监听,xlistView中用的就是这种方式
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(){
@Override
public void onGlobalLayout() {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this); // 记得移出监听,避免内存泄漏
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
}
});
四、延迟加载 后来想到的
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
// int height =view.getWidth(); // 两种获取宽高的方式都行
// int width =view.getHeight();
}
},10);
或者 现在用的最多的
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
int height =view.getMeasuredHeight();
int width =view.getMeasuredWidth();
// int height =view.getWidth(); / 两种获取宽高的方式都行
// int width =view.getHeight();
}
});
方法四种的两种方法,都是等页面绘制完毕后,然后再调用获取宽高的方法,可以获得数值,最下面的是获取layout中的根节点,一旦UI绘制完成,马上就触发了,延迟的还需要10毫秒,比getWindow().getDecorView()这种方法要慢那么 一点,getWindow().getDecorView()可以看成是new Handler().postDelayed()方法中的延迟0毫秒。
今天遇到一个问题,当页面返回时,有软键盘弹出,为了解这个问题,试了各种常规方法,如配置清单配置软键盘的模式,EditText取消焦点,让其他空间获取焦点等,代码控制让软键盘 消失,都不行。突然想到了延迟加载,在延迟加载加载中执行代码控制软键盘消失,试了试,可以了。
private void hideKeyboard() {
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
InputMethodManager manager = ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE));
manager.hideSoftInputFromWindow(NewsSearchActivity.this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
});
}
getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
InputMethodManager manager = ((InputMethodManager)getSystemService(INPUT_METHOD_SERVICE));
manager.hideSoftInputFromWindow(NewsSearchActivity.this.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
});
}