Como trazer a visão na frente de tudo?


130

Eu tenho atividade e muitos widgets, alguns deles têm animações e, devido às animações, alguns dos widgets estão se movendo (traduzindo) um sobre o outro. Por exemplo, a exibição de texto está se movendo sobre alguns botões. . .

Agora, quero que os botões estejam sempre na frente. E quando a visualização de texto estiver em movimento, quero passar por trás dos botões.

Não consigo fazer isso, tentei tudo o que sei e "bringToFront ()" definitivamente não funciona.

note Observação: não quero controlar a ordem z pela ordem de colocação do elemento no layout, porque simplesmente não posso :), o layout é complexo e não consigo colocar todos os botões no início do layout


3
Eu usei um RelativeLayoutcom a exibição "top" aparecendo por último no XML. Veja stackoverflow.com/a/31340762/1121497
Ferran Maylinch

Alguém pode dizer código correspondente no xml de 'BringToFront'
Shirish Herwade

Tente usar a elevação bottomView = elevação: 1dp e topView = elevação: 2dp no seu xml || ViewCompat.setElevation (Exibir, int)
Tlacaelel Ramon Luis 10 /

Respostas:


144

Você pode chamar bringToFront () na exibição que deseja exibir na frente

Isto é um exemplo:

    yourView.bringToFront();

4
Resultado inesperado: usei isso em um layout linear vertical e a vista trazida para a frente apareceu na parte inferior ... Por exemplo, eu tinha A / B / Ce queria trazer Apara a frente, então, depois de executar a.bringToFront(), acabei com um layout como B / C / A.
Ferran Maylinch

2
Então eu descobri LinearLayoutque não pode ser usado com bringToFront. Acabei usando um RelativeLayout. Veja meu comentário sobre a pergunta em si.
Ferran Maylinch

1
Alguém pode dizer código correspondente no xml de 'BringToFront'
Shirish Herwade

Isso resulta no reposicionamento do elemento que estou movendo para a frente por qualquer motivo. ViewCompat.setTranslationZ(view, 1)funciona perfeitamente, por outro lado.
Bimde

1
se eu usei no manifesto android: theme = "@ android: style / Theme.Light.NoTitleBar" em atividade que yourView.bringToFront (); funciona perfeitamente, mas eu usei android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); não funciona Qualquer pista sobre isso.
Rahul

42

Eu estive pesquisando o estouro de pilha para encontrar uma boa resposta e, quando não consegui encontrar uma, procurei os documentos.

ninguém parece ter tropeçado nessa resposta simples ainda:

ViewCompat.setTranslationZ(view, translationZ);

a tradução padrão z é 0,0


Essa é a posição do elemento no eixo Z em px, também conhecido como elevação. setTranslationX moveria a vista ao longo do eixo X (esquerda / direita), setTranslationY ao longo do eixo Y (superior / inferior). O eixo Z é o terceiro eixo.
Xdevs23 22/03

Que tal setZ()? Se bem me lembro, a posição Z da vista é sua elevação mais sua translação Z, afinal.
precisa

2
@ Gensoukyou1337, ViewCompat.setZ(view, yourValueInPixels); view.setZ()funciona apenas na API 21 e superior.
Johnny Cinco

1
Código Java 8 verificado no Android Studio - ele verifica apenas se SDK_INT> = 21, portanto, para <21 api, não tem efeito.
Vadim

32

Uma solução ainda mais simples é editar o XML da atividade. Usar

android:translationZ=""

3
Isso é útil apenas na API Android 21 ou superior.
Isakbob 31/07/19

25

bringToFront()é o caminho certo, mas NOTE que você deve chamar bringToFront()e invalidate()método na visualização de nível mais alto (na visualização raiz), por exemplo:

A hierarquia da sua visualização é:

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

Portanto, quando você animar seus botões (1 a 6), seus botões estarão abaixo (abaixo) de ImageView. Para trazê-lo (acima), ImageViewvocê deve chamar bringToFront()e invalidate()método em seu LinearLayouts. Então, ele funcionará :) ** NOTA: Lembre-se de definir android:clipChildren="false"o layout raiz ou o gradparent_layout da animação-view. Vamos dar uma olhada no meu código real:

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

Algum código em .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!


e se você quiser colocar o botão 6 acima da visualização de imagem e não os outros botões?
Adam Katz

@ AdamKatz: Eu acho que você deve reorganizá-los em outro punho nivelado. Então, traga do seu jeito.
Justin

obrigado Estou tentando colocar apenas um item de uma exibição de reciclador acima de uma exibição, mas deixamos os outros abaixo, bem presos!
Adam Katz

Eu usei o mesmo. Está funcionando bem com um único problema que oculta a barra de ferramentas.
User2980181

Isso funciona com vários níveis? Digamos que eu tenho um ConstraintLayoutque contém um RelativeLayoute outro RelativeLayout, ambos têm o mesmo tamanho que sua raiz ConstraintLayout( match_parent). O primeiro RelativeLayouttem um Buttone também está atrás (em ordem de z) do segundo RelativeLayout. Posso fazer Buttoncom que o primeiro RelativeLayoutapareça como se estivesse em cima de tudo, para que fique visível e clicável usando View::bringToFront()?
oaskamay 13/07/2018


18

Tente FrameLayout, ele oferece a possibilidade de colocar as visualizações uma acima da outra. Você pode criar dois LinearLayouts: um com vistas de segundo plano e outro com vistas de primeiro plano e combiná-los usando o FrameLayout. Espero que isto ajude.


1
Como podemos colocá-lo no topo como um diálogo?
Gaurav Arora

@ Infinidade, você pode criar um FragmentDialog para essa finalidade ou simplesmente usar o Theme.Dialog para sua Atividade.
Egor

Não posso usar o FragmentDialog, pois é incompatível com a API 10. Em segundo lugar, já estou usando um tema para o meu aplicativo. Existe alguma outra maneira? Eu usei o FrameLayout como você disse!
Gaurav Arora

@ Infinidade, você pode usar a versão da biblioteca de compatibilidade do FragmentDialog, disponível na API 4.
Egor

8

Se você estiver usando ConstraintLayout, basta colocar o elemento após os outros elementos para torná-lo na frente do que os outros



3

Pode haver outra maneira que salve o dia. Basta iniciar um novo diálogo com o layout desejado e apenas mostrá-lo. Eu preciso dele para mostrar um loadingView sobre um DialogFragment e essa foi a única maneira de obter sucesso.

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

bringToFront () pode não funcionar em alguns casos como o meu. Mas o conteúdo do layout dialog_top deve substituir qualquer coisa na camada da interface do usuário. Mas, enfim, essa é uma solução feia.


3

Eu enfrentei o mesmo problema. a seguinte solução funcionou para mim.

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

A segunda solução é usar xml adicionando esse atributo à visualização xml

android:translationZ=""

2

Você pode usar o BindingAdapter assim:

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


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

0

Você precisa usar o framelayout. E a melhor maneira de fazer isso é tornar a visualização invisível quando não forem necessárias. Também é necessário definir a posição para cada vista, para que eles se movam de acordo com a posição correspondente


0

Se você estiver usando um, LinearLayoutdeverá ligar myView.bringToFront()e depois ligar parentView.requestLayout()e parentView.invalidate()forçar o pai a redesenhar com a nova ordem filho.


0

Tente usar a elevação, algo como yourview.setElevation(5);


0

Graças ao usuário do Stack sobre essa explicação, eu tenho esse trabalho mesmo no Android 4.1.1

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

No meu uso dinâmico, por exemplo, eu fiz

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

E Bamm!


-2

Organize-os na ordem que você deseja mostrar. Suponha que você queira mostrar a vista 1 na parte superior da vista 2. Em seguida, escreva o código da vista 2 e depois escreva o código da vista 1. Se você não conseguir fazer esse pedido, chame bringToFront () para a visualização raiz do layout que você deseja trazer para a frente.


-32

Você pode definir a visibilidade como falsa em outras visualizações.

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

ou

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

E definir

viewN.setVisibility(View.VISIBLE);

4
Eu preciso que tudo fique visível, esse não é o problema, o problema é a ordem z. se a viabilidade fosse o problema, seria fácil de resolver. . .
Lukap
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.