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

计算视图宽高有几种方式先简单的了解下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;




更多相关文章

  1. Android(安卓)利用SurfaceView实现一个简单的计时器
  2. Android中实现「类方法指令抽取方式」加固方案原理解析
  3. Android(安卓)Architecture Components(六)Room源码分析
  4. Android多点触控实现图片缩放预览
  5. react-native Android截屏长图
  6. 【设计模式与Android】模板方法模式——照葫芦画瓢
  7. Android中的Cursor到底是什么?如何理解Cursor的方法都在做什么事
  8. Android(安卓)Volley完全解析(四),带你从源码的角度理解Volley
  9. Android(安卓)中View的绘制流程(结合图解及伪代码说明)

随机推荐

  1. Android使用百度地图---环境配置和Hello
  2. (笔记)Android的OnGestureListener中onFl
  3. Android独立开发------>前期搭框架准备事
  4. ubuntu 中 gcc/g++版本降级
  5. 【Android】 设置App字体不跟随系统字体
  6. SlidingDrawer
  7. Android(安卓)布局之layout
  8. 简单实现Android底部工具栏
  9. Android(安卓)国际化以及屏幕适配
  10. Android(安卓)Flurry使用说明