237

我想在 Android 中定义 RelativeLayout 视图的 z 顺序。

我知道这样做的一种方法是调用bringToFront.

有没有更好的方法来做到这一点?如果我可以在布局 xml 中定义 z 顺序,那就太好了。

4

13 回答 13

324

最简单的方法就是注意将视图添加到 XML 文件中的顺序。文件中的低位意味着 Z 轴的高位。

编辑:这在 Android 开发者网站上记录在这里这里。(感谢@flightplanner)

于 2010-04-10T18:18:20.257 回答
90

如果你想在代码中做到这一点,你可以做到

View.bringToFront();

文档

于 2013-02-13T06:13:33.417 回答
77

请注意,API 21 及更高版本中的按钮和其他元素具有较高的高度,因此无论父布局如何,都会忽略元素的 xml 顺序。我花了一段时间才弄清楚那个。

于 2016-09-19T12:13:51.987 回答
25

在从 API 级别 21 开始的 Android 中,布局文件中的项目从它们在文件中的排序方式(如正确答案中所述)和它们的高度获得它们的 Z 顺序,更高的高度值意味着项目获得更高的 Z 顺序.

这有时会导致问题,特别是对于经常出现在项目顶部的按钮,根据 XML 的顺序,这些按钮应该按 Z 顺序在它们下方。要解决此问题,只需将android:elevation布局 XML 中的项目设置为匹配您想要实现的 Z 顺序。

我在布局中设置了元素的高度,它将开始投射阴影。如果您不想要这种效果,您可以使用如下代码移除阴影:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   myView.setOutlineProvider(null);
}

我还没有找到任何方法来通过布局 xml 删除提升视图的阴影。

于 2016-07-22T22:52:44.203 回答
16

我遇到了同样的问题:在相对布局的 parentView 中,我有 2 个孩子 childView1 和 childView2。起初,我将 childView1 放在 childView2 之上,并且我希望 childView1 位于 childView2 之上。改变孩子观点的顺序并没有解决我的问题。对我有用的是在 parentView 和我设置的代码中设置android:clipChildren="false" :

childView1.bringToFront();

parentView.invalidate();
于 2014-10-01T08:58:29.180 回答
16

请注意,您可以view.setZ(float)从 API 级别 21 开始使用。在这里您可以找到更多信息。

于 2015-04-17T15:59:55.533 回答
15

自推出以来,我想我会添加一个答案

机器人:翻译Z

XML 字段稍微改变了一些东西。建议运行的其他答案

childView1.bringToFront();

parentView.invalidate();

除了该代码不会将 childView1 放在任何带有硬编码 android:translationZ 的 XML 文件中的视图前面之外,完全可以发现。我遇到了这个问题,一旦我从其他视图中删除了这个字段,bringToFront() 工作得很好。

于 2015-08-20T16:39:04.373 回答
6

API 21 已view.setElevation(float)内置

用于ViewCompat.setElevation(view, float);向后兼容

更多方法ViewCompat.setZ(v, pixels)ViewCompat.setTranslationZ(v, pixels)

另一种方法是收集按钮或视图数组并用于addView添加到 RelativeLayout

于 2017-10-02T10:23:19.433 回答
5

childView.bringToFront() 对我不起作用,所以我将最近最少添加的项目(覆盖所有其他孩子的项目)的 Z 平移设置为负值,如下所示:

lastView.setTranslationZ(-10);

有关更多信息,请参见https://developer.android.com/reference/android/view/View.html#setTranslationZ(float)

于 2016-06-17T00:30:33.097 回答
1

您可以将自定义RelativeLayout与重新定义一起使用

protected int getChildDrawingOrder (int childCount, int i)

请注意 - 此方法将参数i作为“我应该绘制哪个视图i'th”。这是如何ViewPager工作的。它结合 . 设置自定义绘图顺序PageTransformer

于 2016-03-05T14:17:57.833 回答
1

或者将重叠的按钮或视图放在 FrameLayout 中。然后,xml 文件中的 RelativeLayout 将尊重子布局添加时的顺序。

于 2018-12-11T09:58:05.657 回答
0

检查您在 XML 中的某个视图上是否有任何高度。如果是这样,请将高程添加到其他项目或删除高程以解决问题。从那里开始,是视图的顺序决定了什么高于另一个。

于 2018-05-03T08:30:27.483 回答
0

您也可以使用下面的代码示例来实现相同的目的

ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);

这是向后兼容的。这mCardView是一个应该在下面的视图sourceView

于 2019-08-16T10:57:47.880 回答