如何把风景带到万物之前?

我有活动和它上面的很多小部件,他们中的一些有动画,因为动画一些小部件正在移动(翻译)在另一个。例如,文本视图在一些按钮上移动... ..。

现在的问题是,我希望按钮永远在前面。当文本视图移动时,我想移动到按钮后面。

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

注意,我不想按照元素到布局的顺序来控制 z 顺序,因为我根本做不到:) ,布局很复杂,我不能把所有的按钮都放在布局的要求下

238303 次浏览

尝试 FrameLayout,它给你的可能性,把意见一个以上的另一个。您可以创建两个 LinearLayouts: 一个带有背景视图,一个带有前景视图,并使用 FrameLayout将它们组合在一起。希望这个能帮上忙。

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

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

或者

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

准备

viewN.setVisibility(View.VISIBLE);

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

您可以在希望获得的前端视图上调用 bringToFront ()

这是一个例子:

    yourView.bringToFront();

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

你的观点的等级是:

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

因此,当你动画回你的按钮(1-> 6) ,你的按钮将下(下)的 ImageView。为了把它带到(上面) ImageView上,你必须在你的 LinearLayout上调用 bringToFront()invalidate()方法。那么它就会起作用:) 注意: 请记住为您的根布局或 animate-view 的 gradrent _ outs 设置 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_width="match_parent"
android:layout_height="match_parent"
android:background="@color/common_theme_color"
android:orientation="vertical" >


<com.binh.helloworld.customviews.HWActionBar
android:id="@+id/action_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/dimen_actionbar_height"
android:layout_alignParentTop="true"
hw:titleText="@string/app_name" >
</com.binh.helloworld.customviews.HWActionBar>


<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/action_bar"
android:clipChildren="false" >


<LinearLayout
android:id="@+id/layout_top"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:orientation="horizontal" >
</LinearLayout>


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


<LinearLayout
android:id="@+id/layout_bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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);

祝你好运!

我一直在通过堆栈溢出寻找一个好的答案,当我找不到一个,我去查看文件。

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

ViewCompat.setTranslationZ(view, translationZ);

默认转换 z 为0.0

还有别的办法可以挽救局面。只需初始化一个新的对话框,按照需要的布局显示即可。我需要它来显示一个加载视图通过一个对话框片段,这是我成功的唯一途径。

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

BringToFront ()在像我这样的情况下可能不起作用。但是对话框顶部布局的内容必须覆盖 ui 层上的任何内容。但无论如何,这是一个丑陋的变通方案。

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

android:translationZ=""

我也遇到过同样的问题。 下面的方法对我很有效。

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

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

android:translationZ=""

如果您使用的是 LinearLayout,您应该调用 myView.bringToFront(),然后您应该调用 parentView.requestLayout()parentView.invalidate(),以强制家长重新绘制与新的子顺序。

你可以尝试使用 bringChildToFront,你可以检查这个 文件Android 开发者页面中是否有帮助。

如果您使用的是 ConstraintLayout,只需将元素放在其他元素之后,使其位于前面

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

使用 xml 中的此代码

 android:translationZ="90dp"

你可以这样使用 BindingAdapter:

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




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

感谢 Stack 使用者 over 这个的解释,我甚至可以在 Android 4.1.1上使用它

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

例如,在我的动态使用中,我就是这样做的

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

还有 Bamm!

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

重叠视图的顺序实际上取决于4个因素:

  1. 以 dp/sp 表示的属性 android:elevation
  2. 属性 android:translationZ也是以 dp/sp. 来度量的。
  3. 在约束布局中,在组件树中放置视图的顺序也是要显示的顺序。
  4. 在 kotlin/java 代码中通过类似 view.bringToFront()的方法设置的编程顺序。

数字1和2相互兼容,优先于点3和4: 如果你设置 elevation="4dp"为视图1和 translationZ="2dp"为视图2,视图1将总是在上面,而不管数字3和4。

尝试使用 app:srcCompat而不是 android:src