android动态测量控件
2016-07-05 17:30
555 查看
android动态测量控件
通常在实际开发中,为了适配,我们会把View设置为match_parent或者wrap_content、又或者是设置weight权重来分配宽高,而不是使用具体值。那么就出现一个问题了,如果动态测量View的实际宽高。测量宽高的API:android提供了两个API来动态获取View的高:
view.getMeasuredHeight() view.getHeight()
那么这两个API的区别是什么呢?
简单来说就是:
view.getMeasuredHeight() 是由view中的测量方法赋值的,这个值包含了隐藏的高度(比如一个view部分超出屏幕,他也会计算出来)。
view.getHeight() 由view的底部位置减去顶部位置,即实际显示的View的高度,不包含隐藏了的高度。
如果是在View的onMeasure方法后执行上面两个方法,会发现可以得到正确的高度,但是如果是在onCreate等方法中执行就会发现返回的值不正确或者为0,这是为什么呢?
这是因为View的onMeasure()方法在Activity的onCreate();onResume()方法之后执行,此时还没有测量出实际的宽高,还没有进行绘制,所以调用上述的两个API会出现值为0或者数值错误的情况。
测量方法:
1 : 主动请求测量:
view.measure(0, 0); view.getMeasuredWidth(); view.getMeasuredHeight();
说明:
onMeasure传入的两个参数是由父控件的大小,
也可以使用 View.MeasureSpec.makeMeasureSpec(0,mode);设置值
其中mode可以选择
MeasureSpec.UNSPECIFIED 未指定尺寸,比如listview中尺寸由父控件决定 MeasureSpec.EXACTLY 适合match_parent或者具体值 MeasureSpec.AT_MOST 适合wrap_content不确定值
注意:
这种方法不一定能测出正确的值,因为onMesure会多次调用(由于onMesure自上而下,父控件如果对于子控件的宽高不满意,即如子控件没有限制宽高,父控件会重新调用onMesure重新测量),所以测量结果不一定正确。
2 :使用OnPreDrawListener
ViewTreeObserver observer = view.getViewTreeObserver(); observer.addOnPreDrawListener(new OnPreDrawListener() { @Override public boolean onPreDraw() { view.getViewTreeObserver().removeOnPreDrawListener(this); int height = view.getMeasuredHeight(); int width = view.getMeasuredWidth(); return true; } });
说明:
这个是异步解决方法,在onDraw之前执行,onDraw方法执行在onMeasure之后,所以这个监听器可以解决动态获取的问题。
注意:
onPreDraw方法只有return true才会生效,由于onDraw会在view绘制时调用,所以可能会调用多次,务必调用removeOnPreDrawListener方法,防止执行效率问题。onDraw会多次执行,每次view出现都会调用,但onLayout不会,测量后会被记录下来。
3.使用OnGlobalLayoutListener
ViewTreeObserver observer = view.getViewTreeObserver(); observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { view.getViewTreeObserver().removeGlobalOnLayoutListener(this); int height = img.getWidth(); int width = img.getHeight(); } });
说明:
这个也是异步解决方法,在全局onLayout触发时执行。
注意:
这个方法有一定不确定性,而且onLayout执行第一次的数值不一定正确。
4.使用OnLayoutChangeListener
view.addOnLayoutChangeListener(new OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { } });
说明:这个方法OnLayout时调用,而且只有改变时才会触发。
注意:这个方法要求API level 11
相关文章推荐
- Android画图
- android 显示Gift图片
- Tabhost的用法
- android用wifi进行adb调试
- android动画的实现
- Android高清巨图加载方案
- Android事件分发机制
- Android使用Font Awesome显示小图标(二)
- 五步搞定Android开发环境部署——非常详细的Android开发环境搭建教程
- Android Studio --自动删除没有用的资源,给APK减减肥
- 【Android 应用开发】Android 开发环境下载地址
- Android Studio你不知道的调试技巧
- android 屏幕适配攻略(1) 核心概念与单位详解
- Android之图片的颜色处理
- Android apk瘦身
- [Android Studio 权威教程]断点调试和高级调试
- Android 不同应用通过SharedPreference实现共享数据
- Android动态加载启动页
- Android热修复---AndFix
- AndroidStudio里面怎么取消与SVN的关联