如何将视图发送到后台?如何以编程方式控制 z 顺序?

发布于 2024-11-25 08:25:25 字数 301 浏览 7 评论 0 原文

我在将视图发送回去时遇到问题。在 Android 中,我们有一个类似 bringToFront() 的方法,可以将视图放置在另一个视图之上。像这样,我想把视图放在上一张图片的下面。

Android 中有类似 sendToBack()bringToBack() 的方法吗?如果是这样,任何人都可以帮助我吗?

注意:我不想通过在布局中放置项目的顺序来控制 z 顺序,我想以编程方式控制 z 顺序。

我不想隐藏前面的视图,我只是希望它们位于正在移动的视图后面。

I have a problem to send the view to back. In Android we have a method like bringToFront(), to place the view on top of the another view. Like that, I want to put the view on below the previous image.

Is there any method like sendToBack() or bringToBack() in Android. If so, can any one help me in this.

Note: that I do not want to control the z-order by the order of placing items in layout I want to control the z-order programmatically.

I do not want to hide the views on the front I just want them to be behind the view that is moving.

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

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

发布评论

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

评论(13

甜中书 2024-12-02 08:25:25

我意识到其他答案中已经暗示了这一点,但没有人发布代码。我将以下内容保留在实用程序类中,其中有用于处理视图的“帮助器”函数:

public static void sendViewToBack(final View child) {
    final ViewGroup parent = (ViewGroup)child.getParent();
    if (null != parent) {
        parent.removeView(child);
        parent.addView(child, 0);
    }
}

I realize that this has been implied in other answers, but no one posted the code. I keep the following in a utility class where I have "helper" functions for dealing with views:

public static void sendViewToBack(final View child) {
    final ViewGroup parent = (ViewGroup)child.getParent();
    if (null != parent) {
        parent.removeView(child);
        parent.addView(child, 0);
    }
}
去了角落 2024-12-02 08:25:25

没有 sendToBack() 方法。但是,如果您在位置较低的视图上调用 bringToFront() ,您将获得几乎相同的效果。

There is no sendToBack() method. But if you call bringToFront() on the lower positioned view you get almost the same effect.

美人骨 2024-12-02 08:25:25

据我所知,没有内置的解决方案。我猜您正在尝试修改 FrameLayout 中的 z 顺序或类似的内容。

但是,我认为您可以修改布局中包含的子元素的顺序。 RemoveChild...() 和 addView() 方法可以获取位置值,因此您很可能可以交换子元素,这会修改 z 顺序。然而,这似乎有点棘手的解决方案。

或者考虑修改子视图的可见性属性,您可能会得到类似的行为,我认为这会更干净。

编辑:

随着新的 Android 版本,L 开发者预览版,我们似乎终于能够轻松更改视图的 Z 顺序了。 “Elevation”和“TranslationZ”属性可用于救援:https://developer.android .com/preview/material/views-shadows.html

Afaik there's no built-in solution for this. I guess you're trying to modify the z-order in a FrameLayout, or something similar.

However, I think you can modify the order of the contained child elements in the layout. RemoveChild...() and addView() methods can take position values, so you could most likely swap child elements around, and that would modify the z-order. It seems a bit hacky solution however.

Or consider modifying the visibility property of the child views, you may get similar behaviour, and that'd be much cleaner I think.

Edit:

With the new Android version, the L Developer Preview it seems that at last we have the ability to easily change the Z ordering of Views. 'Elevation' and 'TranslationZ' properties to the rescue: https://developer.android.com/preview/material/views-shadows.html

往事随风而去 2024-12-02 08:25:25

在你想要进入最前面的视图上调用 bringToFront() 方法,然后在所有视图上调用 invalidate() 方法,包括你想要在最前面的视图。对所有听众重复同样的操作。

因此,当另一个视图的侦听器被调用时,前一个视图将失效并进入后台。

Call bringToFront() on the view you want to get in the front, and then call the invalidate() method on all the view including the view which you want in the front. Repeat same for all the listeners.

So when another view's listener will get called, the previous view will get invalidated and will be in background.

冷了相思 2024-12-02 08:25:25

这是我用来将视图发送到后面的方法(与bringToFront相反,类似于sendToBack):

    private void moveToBack(View myCurrentView) 
    {
        ViewGroup myViewGroup = ((ViewGroup) myCurrentView.getParent());
        int index = myViewGroup.indexOfChild(myCurrentView);
        for(int i = 0; i<index; i++)
        {
            myViewGroup.bringChildToFront(myViewGroup.getChildAt(i));
        }
    }

希望这有帮助!

Here is the method I am using to send a View to the back (so opposite of bringToFront, kind of sendToBack):

    private void moveToBack(View myCurrentView) 
    {
        ViewGroup myViewGroup = ((ViewGroup) myCurrentView.getParent());
        int index = myViewGroup.indexOfChild(myCurrentView);
        for(int i = 0; i<index; i++)
        {
            myViewGroup.bringChildToFront(myViewGroup.getChildAt(i));
        }
    }

Hope this helps!

無心 2024-12-02 08:25:25

请注意,从 API 级别 21 开始,您可以使用 view.setZ(float)在这里您可以找到更多信息。

Please note that you can use view.setZ(float) starting from API level 21. Here you can find more info.

浪漫人生路 2024-12-02 08:25:25

它工作得很好,就像bringToBack()

public void moveToBack(ViewGroup viewGroup, View v) {
    int s = 1;
    for (int i = 1; i < viewGroup.getChildCount(); i++) {
        if (viewGroup.getChildAt(1) == v) {
            s = 2;
        } else {
            viewGroup.getChildAt(s).bringToFront();
        }
    }
}

it work's fine like bringToBack()

public void moveToBack(ViewGroup viewGroup, View v) {
    int s = 1;
    for (int i = 1; i < viewGroup.getChildCount(); i++) {
        if (viewGroup.getChildAt(1) == v) {
            s = 2;
        } else {
            viewGroup.getChildAt(s).bringToFront();
        }
    }
}
溺深海 2024-12-02 08:25:25

如果您使用的是 appCompat 库,还有另一种方法可以更改低于 21 API 级别的设备的 Z 顺序:

ViewCompat.setTranslationZ(view, zValue);

If you're using appCompat library, there's another way to change Z order for devices lower than 21 API level:

ViewCompat.setTranslationZ(view, zValue);
悲歌长辞 2024-12-02 08:25:25

在您的 XML 文件中,您必须按顺序编写:

<FrameLayout
android:id="@+id/frameLayoutXML"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
<ImageView
 android:id="@+id/imageViewXML"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/floatB_XML"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

在这种情况下,imageView 将位于 FloatingActionButton 的后面。

如果您想更改某些内容,那么您将以编程方式执行此操作:

public class SomeActivity extends AppCompatActivity {

    //declare variables
    ImageView imageView;
    FrameLayout frameLayout;
    FloatingActionButton floatingActionButtonNew;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Here is to call what already exists at XML file
        frameLayout=findViewById(R.id.frameLayoutXML);   
        imageView = findViewById(R.id.imageViewXML);
        //Here is to declare a new Element to add to the view, but is not at XML File
        floatingActionButtonNew=New FloatingActionButton(this);
        frameLayout.removeAllViews();  //here you remove all views.
        frameLayout.addView(imageView);//And you add again the imageView first
        floatingActionButtonNew.setLayoutParams(new 
         RelativeLayout.LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT
        )); //Then you can give some format to your floatingButtonNew

        //And finally  add to the frameLayout the new View in this case the floatingButtonNew
        frameLayout.addView(floatingActionButtonNew);
    }
}

按照视图声明的顺序,您将再次从浮动按钮返回图像。所以先声明的视图将从后声明的视图中返回,而实现顺序的关键是 FrameLayoutremoveAllViews LinearLayout 并在以编程方式添加时再次添加此视图。

In your XML File you must to write in order:

<FrameLayout
android:id="@+id/frameLayoutXML"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
<ImageView
 android:id="@+id/imageViewXML"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/floatB_XML"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>

In this case, the imageView will be back of the FloatingActionButton.

If you want change something, and you will do it programmatically then:

public class SomeActivity extends AppCompatActivity {

    //declare variables
    ImageView imageView;
    FrameLayout frameLayout;
    FloatingActionButton floatingActionButtonNew;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //Here is to call what already exists at XML file
        frameLayout=findViewById(R.id.frameLayoutXML);   
        imageView = findViewById(R.id.imageViewXML);
        //Here is to declare a new Element to add to the view, but is not at XML File
        floatingActionButtonNew=New FloatingActionButton(this);
        frameLayout.removeAllViews();  //here you remove all views.
        frameLayout.addView(imageView);//And you add again the imageView first
        floatingActionButtonNew.setLayoutParams(new 
         RelativeLayout.LayoutParams(
          RelativeLayout.LayoutParams.WRAP_CONTENT,
          RelativeLayout.LayoutParams.WRAP_CONTENT
        )); //Then you can give some format to your floatingButtonNew

        //And finally  add to the frameLayout the new View in this case the floatingButtonNew
        frameLayout.addView(floatingActionButtonNew);
    }
}

In this order of view declarations, you will have again the image back from the floating button. So the view that is declared first will be back from the view that is declared secondly, and the key to achieve the order, is to removeAllViews of a FrameLayout or LinearLayout and add again this views when you are adding programmatically.

﹏雨一样淡蓝的深情 2024-12-02 08:25:25

您还可以尝试使用 ViewGroup.addViewInLayout() 方法的功能,该方法采用索引,确定视图应该位于列表的末尾还是开头

You can also try to use functionality of ViewGroup.addViewInLayout() method which take an index, determining should the view be at the end or at the beginning of the list

水中月 2024-12-02 08:25:25

如果相关视图是按钮,则编程调整需要单行 xml 来实现完整的 z 顺序控制。否则,setElevation()、setZ()、setTranslationZ() 和bringToFront() 都会莫名其妙地让你失败。请参阅下面有关单独线程的描述。

https://stackoverflow.com/a/68674834/14116101

If the views in question are buttons, programmatic adjustments require a single line of xml for full z-order control. Otherwise, setElevation(), setZ(), setTranslationZ(), and bringToFront() will all inexplicably fail you. See description on separate thread below.

https://stackoverflow.com/a/68674834/14116101

月朦胧 2024-12-02 08:25:25

我要么将其可见性设置为 0,要么将其下方的视图置于其前面。

I would either set it's visibility to 0 or just bring the view under it in front of it.

几度春秋 2024-12-02 08:25:25

您可以尝试执行 view.setVisibility(View.INVISIBLE)view.setVisibility(View.GONE)

更新:

向您展示了如何完成你想做的事。

You could try doing view.setVisibility(View.INVISIBLE) or view.setVisibility(View.GONE).

UPDATE:

This shows you how to accomplish what you want to do.

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