在Android中绘制之前测量所有视图层次结构
Posted
技术标签:
【中文标题】在Android中绘制之前测量所有视图层次结构【英文标题】:Measure all view hierarchy before drawing in Android 【发布时间】:2012-07-11 05:54:46 【问题描述】:我有下一个视图层次结构:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:gravity="center">
<LinearLayout
android:layout_
android:layout_
android:background="@drawable/group_bg"
android:gravity="center_vertical"
android:baselineAligned="false">
<LinearLayout
android:id="@+id/itemplace"
android:layout_
android:layout_
android:layout_marginRight="5dp"
android:layout_weight="1" >
<include
android:layout_
android:layout_
layout="@layout/pin" />
</LinearLayout>
<FrameLayout
android:layout_
android:layout_
android:background="@drawable/arrow_black"/>
</LinearLayout>
</LinearLayout>
在绘制此层次结构之前,我需要获取 itemplace 宽度。我无法使用 OnLayoutChangeListener,因为我使用的是 API 级别 7。
我知道我必须使用 measure() 和 layout() 方法来计算视图的大小,但我不知道该怎么做。
我的层次结构中的根视图必须填满屏幕的所有宽度,因此 itemplace 宽度取决于父大小、父填充和 FrameLayout 宽度。
我必须怎么做才能让它变宽?
【问题讨论】:
当您尝试获取长度时,视图的宽度是否返回 0? 【参考方案1】:我找到了获取视图宽度的方法。我可以在 android 测量它之后但在 ViewTreeObserver 中使用 OnPreDrawListener 绘制之前得到它:
view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener()
@Override
public boolean onPreDraw()
int avaliableWidth = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight();
Log.d("width", String.valueOf(avaliableWidth));
return true;
);
来自 Android 文档:
即将绘制视图树时调用的回调方法。 此时,树中的所有视图都已被测量并给出了一个 框架。客户可以使用它来调整他们的滚动边界,甚至 在绘制之前请求一个新的布局。
【讨论】:
但我也希望能够使用 measure() 和 layout() 方法自行计算视图宽度。怎么办?【参考方案2】:这从 API 1 开始可用:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
【讨论】:
我无法更改视图类。我只有从 LayoutInflater 返回的 View 对象。 好吧,你有 View view = ... 并且你需要 view 的 witdh 吗? 当宽度返回0时你使用什么方法? 顶部帖子的视图层次结构我从 LayoutInflater 膨胀并获取 View 对象。我知道,那就是视图必须填满所有屏幕宽度。这就是我所拥有的一切。在绘制层次结构之前,我需要从层次结构中获取一个视图的宽度。这就是全部任务。我已经找到了一种方法——使用 OnPreDrawListener。但是,如果我知道像 Android 那样使用 measure() 和 layout() 获取视图宽度的其他方法,那就太好了。 首先我尝试调用 measure(MeasureSpec.EXACTLY, MeasureSpec.EXACTLY);然后我调用 layout(0, 0, screenWidth, 100); Android文档说,使用这两种方法Android在绘制之前计算视图的宽度和高度。但是使用这个方法后,view.getMeasuredWidth() 返回 0。以上是关于在Android中绘制之前测量所有视图层次结构的主要内容,如果未能解决你的问题,请参考以下文章
Android - 任何Activity的根视图层次结构中存在的所有视图的相对路径生成器