我有活动和很多小部件,其中一些有动画,并且由于动画,一些小部件正在移动(翻译)另一个。例如,文本视图在一些按钮上移动。. .
现在问题是我希望按钮总是在前面。当文本视图移动时,我想移动到按钮后面。
我无法做到这一点,我尝试了我所知道的一切,“bringToFront()”肯定行不通。
请注意,我不想通过将元素放置到布局的顺序来控制 z 顺序,因为我根本做不到 :),布局很复杂,我不能将所有按钮都放在布局的开头
您可以在要放在前面的视图上调用 bringToFront()
这是一个例子:
yourView.bringToFront();
在 xml 中使用此代码
android:translationZ="90dp"
我一直在查看堆栈溢出以找到一个好的答案,当我找不到答案时,我浏览了文档。
似乎没有人偶然发现这个简单的答案:
ViewCompat.setTranslationZ(view, translationZ);
默认翻译 z 为 0.0
一个更简单的解决方案是编辑活动的 XML。利用
android:translationZ=""
bringToFront()
是正确的方法,但请注意,您必须在最高级别视图(在您的根视图下)调用bringToFront()
和invalidate()
方法,例如:
您的视图层次结构是:
-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6
因此,当您为按钮 (1->6) 设置动画时,您的按钮将位于ImageView
. 要把它带到(上面)ImageView
你必须在你的 s上调用bringToFront()
和invalidate()
方法。LinearLayout
然后它将起作用:) **注意:请记住android:clipChildren="false"
为您的根布局或动画视图的 gradparent_layout 设置。先看一下我的真实代码:
.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);
幸运!
试试看FrameLayout
,它使您可以将视图置于另一个之上。您可以创建两个LinearLayouts
:一个带有背景视图,一个带有前景视图,并使用FrameLayout
. 希望这可以帮助。
如果您正在使用ConstraintLayout
,只需将元素放在其他元素之后,使其比其他元素更靠前
您可以尝试使用,您可以在Android 开发者页面bringChildToFront
中查看此文档是否有帮助。
我也面临同样的问题。以下解决方案对我有用。
FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
glFrame.addView(yourView);
glFrame.bringToFront();
glFrame.invalidate();
第二种解决方案是使用 xml 将此属性添加到视图 xml
android:translationZ=""
可能有另一种方法可以节省时间。只需使用所需布局初始化一个新对话框并显示它。我需要它在 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 层上的任何内容。但无论如何,这是一个丑陋的解决方法。
您可以像这样使用 BindingAdapter:
@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
if (flag) {
view.bringToFront();
}
}
<ImageView
...
app:bringToFront="@{true}"/>
您需要使用框架布局。更好的方法是在不需要时使视图不可见。您还需要为每个视图设置位置,以便它们根据相应的位置移动
按照您要显示的顺序排列它们。假设,您想在视图 2 的顶部显示视图 1。然后编写视图 2 代码,然后编写视图 1 代码。如果您不能执行此排序,则调用bringToFront() 到您想要放在前面的布局的根视图。
如果您使用的是 aLinearLayout
您应该调用myView.bringToFront()
并且在您应该调用parentView.requestLayout()
and之后parentView.invalidate()
强制父级使用新的子级重绘订单。
如果您的最低 api 级别为 21,则可以使用elevation
属性。
您可以将其他视图的可见性设置为 false。
view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...
或者
view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...
并设置
viewN.setVisibility(View.VISIBLE);