如何让一切眼前一亮?

Posted

技术标签:

【中文标题】如何让一切眼前一亮?【英文标题】:How to bring view in front of everything? 【发布时间】:2011-10-09 05:05:31 【问题描述】:

我有活动和很多小部件,其中一些有动画,并且由于动画,一些小部件正在一个接一个地移动(平移)。例如,文本视图在一些按钮上移动。 . .

现在问题是我希望按钮始终位于前面。当文本视图移动时,我想移动到按钮后面。

我无法做到这一点我尝试了我所知道的一切,“bringToFront()”肯定不起作用。

请注意,我不想通过将元素放置到布局的顺序来控制 z 顺序,因为我根本做不到 :),布局很复杂,我无法将所有按钮都放在布局的开头

【问题讨论】:

我使用了RelativeLayout,“顶部”视图最后出现在 XML 中。见***.com/a/31340762/1121497 谁能告诉'bringToFront'的xml中对应的代码 尝试在您的 xml 中使用海拔 bottomView=elevation:1dp 和 topView=elevation:2dp || ViewCompat.setElevation(View, int) 【参考方案1】:

试试FrameLayout,它使您可以将视图置于另一个之上。您可以创建两个LinearLayouts:一个带有背景视图,一个带有前景视图,并使用FrameLayout 组合它们。希望这会有所帮助。

【讨论】:

我们怎样才能把它像对话框一样置顶? @Infinity,您可以为此创建一个 FragmentDialog,或者只为您的 Activity 使用 Theme.Dialog。 我不能使用 FragmentDialog,因为它与 API 10 不兼容。其次,我已经为我的应用程序使用了主题。还有其他方法吗?就像你说的那样,我已经使用了 FrameLayout! @Infinity,您可以使用 API 4 中提供的 FragmentDialog 的兼容库版本。【参考方案2】:

您可以将其他视图的可见性设置为 false。

view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...

view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...

并设置

viewN.setVisibility(View.VISIBLE);

【讨论】:

我需要所有内容都可见,这不是问题,问题是 z 顺序。如果生存能力是问题,那将很容易解决。 . .【参考方案3】:

您需要使用框架布局。更好的方法是在不需要时使视图不可见。此外,您需要为每个视图设置位置,以便它们根据相应的位置移动

【讨论】:

【参考方案4】:

您可以在要放在前面的视图上调用bringToFront()

这是一个例子:

    yourView.bringToFront();

【讨论】:

意外结果:我在垂直线性布局中使用它,并且放在前面的视图出现在底部...例如,我有A / B / C,想把A放在前面,所以在运行a.bringToFront() 之后,我最终得到了类似B / C / A 的布局。 所以我发现LinearLayout不能和bringToFront一起使用。我最终使用了RelativeLayout。请参阅我对问题本身的评论。 谁能告诉'bringToFront'的xml中对应的代码 无论出于何种原因,这都会导致我移动到前面的元素重新定位。另一方面,ViewCompat.setTranslationZ(view, 1) 完美运行。 如果我在清单中使用 android:theme="@android:style/Theme.Light.NoTitleBar" 在活动中比 yourView.bringToFront();效果很好,但我使用了 android:theme="@android:style/Theme.AppCompat.Light.NoActionBar" yourView.bringToFront();不起作用。关于那个的任何线索。【参考方案5】:

bringToFront() 是正确的方法,但是请注意,您必须在***别的视图(在您的根视图下)调用 bringToFront()invalidate() 方法,例如:

您的视图层次结构是:

-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6

因此,当您为按钮 (1->6) 设置动画时,您的按钮将位于(下方)ImageView 下方。要将它带到(上方)ImageView,您必须在您的LinearLayouts 上调用bringToFront()invalidate() 方法。然后它将起作用:) **注意:请记住为您的根布局或 animate-view 的 gradparent_layout 设置 android:clipChildren="false"。来看看我的真实代码:

.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hw="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_parent"
    android:layout_
    android:layout_
    android:background="@color/common_theme_color"
    android:orientation="vertical" >

    <com.binh.helloworld.customviews.HWActionBar
        android:id="@+id/action_bar"
        android:layout_
        android:layout_
        android:layout_alignParentTop="true"
        hw:titleText="@string/app_name" >
    </com.binh.helloworld.customviews.HWActionBar>

    <RelativeLayout
        android:layout_
        android:layout_
        android:layout_below="@id/action_bar"
        android:clipChildren="false" >

        <LinearLayout
            android:id="@+id/layout_top"
            android:layout_
            android:layout_
            android:layout_alignParentTop="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>

        <ImageView
            android:id="@+id/imgv_main"
            android:layout_
            android:layout_
            android:layout_centerInParent="true"
            android:contentDescription="@string/app_name"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_
            android:layout_
            android:layout_alignParentBottom="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

.java 中的一些代码

private LinearLayout layoutTop, layoutBottom;
...
layoutTop = (LinearLayout) rootView.findViewById(R.id.layout_top);
layoutBottom = (LinearLayout) rootView.findViewById(R.id.layout_bottom);
...
//when animate back
//dragedView is my layoutTop's child view (i added programmatically) (like buttons in above example) 
dragedView.setVisibility(View.GONE);
layoutTop.bringToFront();
layoutTop.invalidate();
dragedView.startAnimation(animation); // TranslateAnimation
dragedView.setVisibility(View.VISIBLE);

幸运!

【讨论】:

如果您只想将按钮 6 放在图像视图上方而不是其他按钮,该怎么办? @AdamKatz:我认为您必须将它们重新组织成另一个级别的拳头。然后,把它带到你的路上。 谢谢,我试图将回收站视图中的一个项目放在视图上方,但将其他项目留在其下方,非常卡住! 我也用过。它可以很好地解决一个隐藏工具栏的问题。 这是否适用于多个级别?假设我有一个 ConstraintLayout 包含一个 RelativeLayout 和另一个 RelativeLayout,它们的大小都与其根 ConstraintLayout (match_parent) 相同。第一个RelativeLayout 有一个Button,并且也在(z-order-wise)第二个RelativeLayout 后面。我可以使用View::bringToFront() 使第一个RelativeLayout 中的Button 看起来好像位于所有内容之上,以便它可见且可点击吗?【参考方案6】:

我一直在查看堆栈溢出以找到一个好的答案,当我找不到答案时,我翻阅了文档。

似乎还没有人偶然发现这个简单的答案:

ViewCompat.setTranslationZ(view, translationZ);

默认平移 z 为 0.0

【讨论】:

即元素在Z轴上的位置,单位px,也称为高程。 setTranslationX 将沿 X 轴(左/右)移动视图,setTranslationY 沿 Y 轴(上/下)移动。 Z 轴是第 3 轴。 setZ() 怎么样?如果我没记错的话,视图的 Z 位置毕竟是它的仰角加上它的平移 Z。 @Gensoukyou1337,然后是 ViewCompat.setZ(view, yourValueInPixels); view.setZ() 仅适用于 API 21 及更高版本。 检查了 Android Studio 中的 Java 8 代码 - 它只检查 SDK_INT >= 21,所以对于 【参考方案7】:

还有另一种方法可以节省时间。只需初始化一个具有所需布局的新对话框并显示它。我需要它来在 DialogFragment 上显示 loadingView,这是我成功的唯一方法。

Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();

bringToFront() 在某些情况下可能不起作用,例如我的情况。但是 dialog_top 布局的内容必须覆盖 ui 层上的任何内容。但无论如何,这是一个丑陋的解决方法。

【讨论】:

【参考方案8】:

一个更简单的解决方案是编辑活动的 XML。使用

android:translationZ=""

【讨论】:

这仅适用于 Android API 21 或更高版本。【参考方案9】:

我也遇到过同样的问题。 以下解决方案对我有用。

 FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
        glFrame.addView(yourView);
        glFrame.bringToFront();
        glFrame.invalidate();

第二个解决方案是使用 xml 将此属性添加到视图 xml

android:translationZ=""

【讨论】:

【参考方案10】:

如果您使用LinearLayout,则应调用myView.bringToFront(),然后调用parentView.requestLayout()parentView.invalidate() 以强制父级使用新的子级重绘订单。

【讨论】:

【参考方案11】:

您可以尝试使用bringChildToFront,您可以在Android Developers page中查看这个documentation是否有帮助。

【讨论】:

【参考方案12】:

如果您使用ConstraintLayout,只需将元素放在其他元素之后,使其比其他元素更靠前

【讨论】:

【参考方案13】:

按照您想要显示的顺序排列它们。假设,您想在视图 2 上显示视图 1。然后编写视图 2 代码,然后编写视图 1 代码。如果您不能执行此排序,则调用bringToFront() 到您想要放在前面的布局的根视图。

【讨论】:

【参考方案14】:

在 xml 中使用此代码

 android:translationZ="90dp"

【讨论】:

90dp 是从哪里来的? 手动输入。您可以根据自己的要求进行尝试。 45dp 或 135dp 或 180dp 或 270dp 你不能只使用 1dp 吗? 需要 API 21+ translationZ 值 (90dp) 添加到为 android:elevation 提供的值中。所以,translationZ + elevation 将决定顺序。总和最高的视图将在前面。仅次于它的下一个最高点,依此类推。【参考方案15】:

您可以像这样使用 BindingAdapter:

@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) 
    if (flag) 
        view.bringToFront();
    



  <ImageView
        ...
        app:bringToFront="@true"/>

【讨论】:

【参考方案16】:

感谢 Stack user over this 的解释,即使在 Android 4.1.1 上我也能正常工作

((View)myView.getParent()).requestLayout();
myView.bringToFront();

以我的动态使用为例,我做到了

public void onMyClick(View v)
     
     ((View)v.getParent()).requestLayout();
     v.bringToFront();
     

还有巴姆!

【讨论】:

【参考方案17】:

如果您的最低 api 级别为 21,您可以使用elevation 属性。

【讨论】:

以上是关于如何让一切眼前一亮?的主要内容,如果未能解决你的问题,请参考以下文章

面试时遇到一致性哈希算法这样回答会让面试官眼前一亮

7 个超实用的 MySQL 语句写法,让同事们眼前一亮!

Redesign后的Microsoft Office图标,是否真的让我们眼前一亮

7 个超实用的 MySQL 语句写法,让同事们眼前一亮!

7 个超实用的 MySQL 语句写法,让同事们眼前一亮!

css炫酷动画让面试官眼前一亮的故障风格文字动画