如何让一切眼前一亮?
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
,您必须在您的LinearLayout
s 上调用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
属性。
【讨论】:
以上是关于如何让一切眼前一亮?的主要内容,如果未能解决你的问题,请参考以下文章