【问题标题】:Defining Z order of views of RelativeLayout in Android在Android中定义RelativeLayout视图的Z顺序
【发布时间】:2011-02-06 13:10:12
【问题描述】:

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

我知道这样做的一种方法是致电bringToFront

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

【问题讨论】:

  • View.bringToFront();是分析器

标签: android android-relativelayout z-order


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    您可以使用自定义RelativeLayout 重新定义

    protected int getChildDrawingOrder (int childCount, int i)

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

    【讨论】:

      【解决方案3】:

      API 21 有 view.setElevation(float) 内置

      使用ViewCompat.setElevation(view, float); 实现向后兼容性

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

            【解决方案6】:

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

            【讨论】:

            • 对我来说,这个错误的解决方案是在我想要在按钮上呈现的视图上调用 setElevation(1000)。
            • setElevation() 需要 API 级别 21
            【解决方案7】:

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

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

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

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

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

            【讨论】:

            • 如cmets中提到的,可以使用android:elevation="1000dp"。这种方式不会渲染阴影。
            【解决方案8】:

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

            lastView.setTranslationZ(-10);

            查看https://developer.android.com/reference/android/view/View.html#setTranslationZ(float)了解更多信息

            【讨论】:

              【解决方案9】:

              自从引入

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

              android:translationZ

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

              childView1.bringToFront();
              
              parentView.invalidate();
              

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

              【讨论】:

              • 这也适用于 android 5 的elevation
              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

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

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

                【讨论】:

                • 不幸的是,这并不总是可以改变的。例如,在相对布局中,每个元素只能相对于文件中先前定义的元素进行布局
                • Casebash,我不认为你必须使用“@+id/your_element_before_its_defined”,然后在稍后定义的元素中使用相同的 id。我可能错了,这些布局对我来说非常棘手,但我绝对觉得它有效。
                • tjb 是对的(我很高兴他是对的)。在第一次提到 id 时使用@+id,例如layout_above="@+id/some_id"
                • 你也可以把放到一个values xml文件中,然后你可以在任何地方引用它。
                • 我知道我迟到了大约 3 年,但作为对@hpique 的回答,这已记录在 here
                【解决方案12】:

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

                childView1.bringToFront();
                
                parentView.invalidate();
                

                【讨论】:

                • 这行得通,Android 让我很伤心。 child.bringToFront()parent.invalidate() 有效,但 parent.bringChildToFront(child) 无效。我们都期望操作系统的逻辑在哪里?
                • 为了使一些视图动画化(X 和 Y 的翻译),我尝试了 LinearLayout、FrameLayout 和 RelativeLayout 的几种组合,但总是存在问题(与重叠或不成比例的大小有关)。最后android:clipChildren="false" 成功了。谢谢!
                【解决方案13】:

                如果您想在代码中执行此操作 你可以做

                View.bringToFront();
                

                docs

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-08-25
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2018-08-12
                  相关资源
                  最近更新 更多