android 测量控件视图的方法

在实际项目中经常要用到 测量一个控件或者视图的高,宽。然后根据这个高宽进行一些逻辑。

计算视图宽高有几种方式先简单的了解下android 视图的绘制过程会促进理解。


一、android View绘制过程简介

“绘制布局由两个遍历过程组成:测量过程布局过程

测量过程由measure(int, int)方法完成,该方法从上到下遍历视图树。在递归遍历过程中,每个视图都会向下层传递尺寸和规格。当measure方法遍历结束,每个视图都保存了各自的尺寸信息。

布局过程由layout(int, int, int,int)方法完成,该方法也是由上而下遍历视图树,在遍历过程中,每个父视图通过测量过程的结果定位所有子视图的位置信息。”


为了理解这个概念,下面分析ViewGroup的绘制过程。

第一步是测量ViewGroup的宽度和高度,在onMeasure()方法中完成这步操作。在该方法中,ViewGroup通过遍历所有子视图计算出它的大小。

最后一步操作,在onLayout()方法中完成,在该方法中,ViewGroup利用上一步计算出的测量信息,布局所有子视图。

摘自:《android开发必知的50个诀窍》  讲的很简洁


二、具体测量的办法

在onCreate() 方法里直接 view.getWidth,getHeight  得到的都是0  徒劳。因为视图还没准备好

当onCreate()方法被调用时,会通过LayoutInflater将XML布局文件填充到ContentView。填充过程只包括创建视图,却不包括设置其大小


a、最简单的,比较取巧的方式

重写 onWindowFocusChanged(boolean hasFocus)  方法在该方法中测量控件高,宽。

参数hasFocus 为true收到焦点,false失去焦点。这个方法在onResume之前onCreate 后调用。 失去焦点还会调用一次

注:这个方法中是可以测量控件的,但是这个方法随着生命期会多次调用 

生命期见:

1: entry: onStart---->onResume---->onAttachedToWindow----------->onWindowVisibilityChanged--visibility=0---------->onWindowFocusChanged(true)------->

2. exit:  onPause---->onStop---->onWindowFocusChanged(false)  ---------------------- (lockscreen)

3. exit : onPause----->onWindowFocusChanged(false)----->onWindowVisibilityChanged--visibility=8------>onStop(to another activity)

生命期参考: http://blog.csdn.net/pi9nc/article/details/9237031



b、视图延时测量

groundView.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub

MaxLegth = (int) (groundView.getWidth() * 0.5);
}
});


延迟测量的另一个方法 还未验证;

getWindow().getDecorView().post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub

MaxLegth = (int) (groundView.getWidth() * 0.5);
}
});



c、观察者监听视图 ViewTreeObserver

监听者模式,添加监听器,每次view 绘制前都会通知该监听者

ViewTreeObserver otg = groundView.getViewTreeObserver();
otg.addOnPreDrawListener(new OnPreDrawListener() {

@Override
public boolean onPreDraw() {
// TODO Auto-generated method stub
Log.d("Tag", "width; " + groundView.getWidth());


return true; // 注意:看log可以知道。返回tue 退出来, 完成该次测量。 返回false就一直测
}
});



测量的例子


测量屏幕大小:

getWindowManager().getDefaultDisplay().getMetrics(dm);

int width = dm.widthPixels;

int height = dm.heightPixels;


测量状态栏高度(顶部有电量栏)

Rect frame = new Rect();  

getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);  

int statusBarHeight = frame.top


listview  gridview 等高度扩展

@Override  
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,  
            MeasureSpec.AT_MOST);  
    super.onMeasure(widthMeasureSpec, expandSpec);  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值