如何让视野呈现在一切事物面前?

发布于 2024-11-25 02:27:37 字数 239 浏览 7 评论 0原文

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

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

我无法实现这一目标,我尝试了我所知道的一切,并且“bringToFront()”肯定不起作用。

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

I have activity and a lot of widgets on it, some of them have animations and because of the animations some of the widgets are moving (translating) one over another. For example the text view is moving over some buttons . . .

Now the thing is I want the buttons to be always on the front. And when the textview is moving I want to move behind the buttons.

I can not achieve this I tried everything I know, and "bringToFront()" definitelly doesn't work.

note I do not want to control the z-order by the order of placing element to layout cause I simply can't :), the layout is complex and I can not place all the buttons at the begging of the layout

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

英雄似剑 2024-12-02 02:27:38

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

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

数字 1 和 2 相互竞争并优先于点 3 和 4:如果您为视图 1 和 translationZ="2dp" 设置 elevation="4dp"对于视图 2,视图 1 将始终位于顶部,无论数字 3 和 4 是什么。

The order of the overlapping views really depends of 4 things:

  1. The attribute android:elevation which is measured in dp/sp
  2. The attribute android:translationZ which is also measured in dp/sp.
  3. In Constraint Layout, the order in which you put the views in your Component Tree is also the order to be shown.
  4. The programmatically order that you set through methods like view.bringToFront() in your kotlin/java code.

The numerals 1 and 2 compite with each other and take preference over the points 3 and 4: if you set elevation="4dp" for View 1 and translationZ="2dp" for View 2, View 1 will always be on top regardless of the numerals 3 and 4.

找个人就嫁了吧 2024-12-02 02:27:38

如果您的最低 api 级别为 21,则可以使用 elevation 属性。并且您可以将视图重新排序到其他视图的底部,以将其置于前面。但如果其他视图的高度较高,它们将位于您的视图之上。

You can use elevation attribute if your minimum api level is 21. And you can reorder view to the bottom of other views to bring it to front. But if elevation of other views is higher, they will be on top of your view.

2024-12-02 02:27:38

感谢 Stack 用户 this 解释,即使在 Android 4.1.1 上,我也能做到这一点。

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

在我的动态使用中,例如,我做了

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

And Bamm !

Thanks to Stack user over this explanation, I've got this working even on Android 4.1.1

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

On my dynamic use, for example, I did

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

And Bamm !

初吻给了烟 2024-12-02 02:27:38

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

If you are using a LinearLayout you should call myView.bringToFront() and after you should call parentView.requestLayout() and parentView.invalidate() to force the parent to redraw with the new child order.

栖竹 2024-12-02 02:27:38

按照您想要显示的顺序排列它们。假设您想在视图 2 之上显示视图 1。然后编写视图 2 代码,然后编写视图 1 代码。如果您无法执行此排序,请对要置于前面的布局的根视图调用 BringToFront() 。

Arrange them in the order you wants to show. Suppose, you wanna show view 1 on top of view 2. Then write view 2 code then write view 1 code. If you cant does this ordering, then call bringToFront() to the root view of the layout you wants to bring in front.

把人绕傻吧 2024-12-02 02:27:38

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

Try to use app:srcCompat instead of android:src

可是我不能没有你 2024-12-02 02:27:38

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

You need to use framelayout. And the better way to do this is to make the view invisible when thay are not require. Also you need to set the position for each and every view,So that they will move according to there corresponding position

感情废物 2024-12-02 02:27:38

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

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

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

并设置

viewN.setVisibility(View.VISIBLE);

You can set visibility to false of other views.

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

or

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

and set

viewN.setVisibility(View.VISIBLE);
千鲤 2024-12-02 02:27:37

你可以在你想要的视图上调用bringToFront(),

这是一个例子:

    yourView.bringToFront();

You can call bringToFront() on the view you want to get in the front

This is an example:

    yourView.bringToFront();
审判长 2024-12-02 02:27:37

在 xml 中使用此代码

 android:translationZ="90dp"

With this code in xml

 android:translationZ="90dp"
花落人断肠 2024-12-02 02:27:37

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

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

ViewCompat.setTranslationZ(view, translationZ);

默认翻译 z 是 0.0

I've been looking through stack overflow to find a good answer and when i couldn't find one i went looking through the docs.

no one seems to have stumbled on this simple answer yet:

ViewCompat.setTranslationZ(view, translationZ);

default translation z is 0.0

⊕婉儿 2024-12-02 02:27:37

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

android:translationZ=""

An even simpler solution is to edit the XML of the activity. Use

android:translationZ=""
暮凉 2024-12-02 02:27:37

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

你的视图的层次结构是:

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

所以,当你用动画返回你的按钮(1->6)时,你的按钮将在ImageView下面(下面)。要将其置于 ImageView 上方(上方),您必须在 LinearLayout 上调用 bringToFront()invalidate() 方法>s。然后就可以工作了:)
**注意:请记住为您的根布局或 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_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);

GLuck!

bringToFront() is the right way, but, NOTE that you must call bringToFront() and invalidate() method on highest-level view (under your root view), for e.g.:

Your view's hierarchy is:

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

So, when you animate back your buttons (1->6), your buttons will under (below) the ImageView. To bring it over (above) the ImageView you must call bringToFront() and invalidate() method on your LinearLayouts. Then it will work :)
**NOTE: Remember to set android:clipChildren="false" for your root layout or animate-view's gradparent_layout. Let's take a look at my real code:

.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>

Some code in .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);

GLuck!

执着的年纪 2024-12-02 02:27:37

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

If you are using ConstraintLayout, just put the element after the other elements to make it on front than the others

昨迟人 2024-12-02 02:27:37

尝试一下FrameLayout,它使您可以将视图放在另一个视图之上。您可以创建两个 LinearLayouts:一个具有背景视图,一个具有前景视图,并使用 FrameLayout 将它们组合起来。希望这有帮助。

Try FrameLayout, it gives you the possibility to put views one above another. You can create two LinearLayouts: one with the background views, and one with foreground views, and combine them using the FrameLayout. Hope this helps.

铃予 2024-12-02 02:27:37

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

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

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

android:translationZ=""

i have faced the same problem.
the following solution have worked for me.

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

2nd solution is by using xml adding this attribute to the view xml

android:translationZ=""
弥繁 2024-12-02 02:27:37

您可以尝试使用bringChildToFront,您可以检查这个文档Android 开发者页面。

You can try to use the bringChildToFront, you can check if this documentation is helpful in the Android Developers page.

等待圉鍢 2024-12-02 02:27:37

还有另一种方法可以挽救局面。只需初始化一个具有所需布局的新对话框并显示它即可。我需要它在 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层上的任何内容。但无论如何,这是一个丑陋的解决方法。

There can be another way which saves the day. Just init a new Dialog with desired layout and just show it. I need it for showing a loadingView over a DialogFragment and this was the only way I succeed.

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

bringToFront() might not work in some cases like mine. But content of dialog_top layout must override anything on the ui layer. But anyway, this is an ugly workaround.

没企图 2024-12-02 02:27:37

您可以像这样使用 BindingAdapter:

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


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

You can use BindingAdapter like this:

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


  <ImageView
        ...
        app:bringToFront="@{true}"/>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文