【发布时间】:2014-03-18 05:42:32
【问题描述】:
在视图层次结构中:
Window > ViewGroup (root) > ViewGroup[...] > View (child)
我需要知道深子onMeasure事件中的根维度。
示例:
@Override
protected void onMeasure(int wMS, int hMS) {
int desiredW = Math.round(rootW * factorW);
int desiredH = Math.round(rootH * factorH);
/* ... compute final dimensions ... */
setMeasuredDimension(finalW, finalH);
}
注意:此时,getRootView 和 getWindow 维度等于 0,因为孩子必须在父母之前setMeasuredDimention
考虑到很多孩子需要这个维度,就去做吧:
-
我创建了一个界面:
public interface OnRootSizeChanged { public void onRootSizeChanged(int w, int h); } -
我实现了我的孩子,它现在实现了
OnRootSizeChanged接口:private int rootW; private int rootH; @Override public void onRootSizeChanged(int w, int h) { rootW = w; rootH = h; } -
我实现了根视图:
@Override protected void onMeasure(int wMS, int hMS) { int w = MeasureSpec.getSize(wMS); int h = MeasureSpec.getSize(hMS); dispatchOnRootSizeChange(this, w, h); super.onMeasure(wMS, hMS); } private void dispatchOnRootSizeChange(ViewGroup v, int w, int h) { for (int i = 0, n = v.getChildCount(); i < n; i++) { View child = v.getChildAt(i); if (child instanceof OnRootSizeChanged) ((OnRootSizeChanged) child).onRootSizeChanged(w, h); if (child instanceof ViewGroup) dispatchOnRootSizeChange((ViewGroup) child, w, h); } }
我的问题是:
- 我是否有更简单的方法来做到这一点而无需递归或更好的实践?
更新:对于 ViewGroup[...] breabcrumb 中的 ViewPager 元素,此方法无效。当ViewPager 实例化子页面时,他们还没有收到OnRootSizeChanged 事件所以:
- 孩子要问根维度,没有根告诉孩子他的维度
于是我从一个深奥的孩子那里搜索了如何定位root来问他:
-
getRootView()似乎不是针对setContentView()附加的视图 -
getWindow().getDecorView()要么
一种可能的方法是:
-
在孩子身上:
@Override protected void onMeasure(int wMS, int hMS) { ViewParent parent = getParent(); while (parent instanceof RootViewClass == false) parent = parent.getParent(); RootViewClass root = (RootViewClass) parent; int desiredW = Math.round(root.w * factorW); int desiredH = Math.round(root.h * factorH); /* ... compute final dimensions ... */ setMeasuredDimension(finalW, finalH); } -
在
RootViewClass的根实例上:public int w, h; @Override protected void onMeasure(int wMS, int hMS) { w = MeasureSpec.getSize(wMS); h = MeasureSpec.getSize(hMS); super.onMeasure(wMS, hMS); }
但是对于很多孩子,我认为这不是一个好习惯。如果我可以在不使用循环的情况下找到根视图。
【问题讨论】:
-
为什么不能简单地使用循环?视图层次结构深度应该很小,并且您应该在其他地方一次获得对父级的引用,这样您就不会在每次调用
onMeasure()时都进行循环。 -
如果我找不到其他解决方案,我会这样做,但我觉得这不是一个好习惯。另外,也许我忽略了一个更简单,更相关的解决方案?这是我的问题的对象
-
你试图从孩子身上看到父母有什么限制,这也不是一个好习惯。我没有看到任何其他方式,但是您不需要循环,您只需要在这些子视图中引用对根的引用(您将在活动级别获得一个,因此您只需查找一次), 根,它将存储每次最后一个约束以使它们可用于子级。
-
为了让您更好地理解我的目标,我开发了一个可调整大小的应用程序,它必须适应窗口的大小。所有的 UI 必须始终对用户可见(作为多屏幕尺寸的 openGL 游戏),小窗口的可滚动视图对我不感兴趣,我需要缩放所有视图。所以我所有的元素都取决于我的根视图尺寸。在大多数情况下,我使用父维度来计算子维度,但在某些情况下,我需要恢复根维度原点。可能是我以错误的方式参与?如果您有一些提示,我会非常认可
-
为什么不自定义根布局呢?如果所有 UI 控件都必须可见,则此根视图将根据当前尺寸对其子级施加固定尺寸(这将进一步传播给它们的子级)。