Come far apparire davanti a tutto?


130

Ho attività e molti widget su di esso, alcuni hanno animazioni e a causa delle animazioni alcuni dei widget si stanno spostando (traducendo) uno sopra l'altro. Ad esempio, la visualizzazione del testo si sposta su alcuni pulsanti. . .

Ora il fatto è che voglio che i pulsanti siano sempre sul davanti. E quando la visualizzazione del testo si sposta, voglio spostarmi dietro i pulsanti.

Non riesco a raggiungere questo obiettivo, ho provato tutto quello che so, e "bringToFront ()" definitelly non funziona.

nota Non voglio controllare l'ordine z dall'ordine di posizionamento dell'elemento nel layout perché semplicemente non posso :), il layout è complesso e non riesco a posizionare tutti i pulsanti sull'accattonaggio del layout


3
Ho usato un RelativeLayoutcon la vista "top" che appare per ultima nell'XML. Vedere stackoverflow.com/a/31340762/1121497
Ferran Maylinch

qualcuno può dire il codice corrispondente in xml di 'bringToFront'
Shirish Herwade,

Prova a utilizzare elevazione bottomView = elevazione: 1dp e topView = elevazione: 2dp nel tuo xml || ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

Risposte:


144

Puoi chiamare bringToFront () sulla vista che vuoi ottenere in primo piano

Questo è un esempio:

    yourView.bringToFront();

4
Risultato inaspettato: l'ho usato in un layout lineare verticale e la vista in primo piano è apparsa in basso ... Ad esempio, avevo A / B / Ce volevo portare Ain primo piano, quindi dopo l'esecuzione a.bringToFront()ho finito con un layout simile B / C / A.
Ferran Maylinch,

2
Quindi ho scoperto che LinearLayoutnon può essere usato con bringToFront. Ho finito per usare a RelativeLayout. Vedi il mio commento sulla domanda stessa.
Ferran Maylinch,

1
qualcuno può dire il codice corrispondente in xml di 'bringToFront'
Shirish Herwade,

Ciò comporta il riposizionamento dell'elemento che mi sposto in avanti per qualsiasi motivo. ViewCompat.setTranslationZ(view, 1)funziona perfettamente d'altra parte.
Bimde,

1
se ho usato in manifest android: theme = "@ android: style / Theme.Light.NoTitleBar" in attività di yourView.bringToFront (); funziona perfettamente, ma ho usato android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); non funziona Qualche idea su quello.
Rahul,

42

Ho cercato attraverso lo stack overflow per trovare una buona risposta e quando non sono riuscito a trovarne uno sono andato a cercare tra i documenti.

nessuno sembra essersi imbattuto in questa semplice risposta ancora:

ViewCompat.setTranslationZ(view, translationZ);

la traduzione predefinita z è 0,0


Questa è la posizione dell'elemento sull'asse Z in px, noto anche come elevazione. setTranslationX sposterebbe la vista lungo l'asse X (sinistra / destra), setTranslationY lungo l'asse Y (alto / basso). L'asse Z è il 3 ° asse.
xdevs23

Che dire setZ()? Se ricordo bene, la posizione Z della vista è la sua elevazione più la sua traduzione Z, dopo tutto.
Gensoukyou1337,

2
@ Gensoukyou1337, quindi ViewCompat.setZ(view, yourValueInPixels); view.setZ()funziona solo su API 21 e successive.
Johnny Five,

1
Codice Java 8 verificato in Android Studio: controlla solo se SDK_INT> = 21, quindi per <21 api non ha alcun effetto.
Vadim,

32

Una soluzione ancora più semplice è modificare l'XML dell'attività. Uso

android:translationZ=""

3
Questo è utile solo nell'API Android 21 o successiva.
Isakbob,

25

bringToFront()è il modo giusto, ma, NOTA, è necessario chiamare bringToFront()e invalidate()metodo sulla vista di livello più alto (sotto la vista di root), ad esempio:

La gerarchia della tua vista è:

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

Quindi, quando animi indietro i tuoi pulsanti (1-> 6), i tuoi pulsanti saranno sotto (sotto) il ImageView. Per portarlo sopra (sopra) ImageViewdevi chiamare bringToFront()e invalidate()metodo sul tuo LinearLayouttelefono. Quindi funzionerà :) ** NOTA: Ricorda di impostare android:clipChildren="false"il layout di root o gradparent_layout di animate-view. Diamo un'occhiata al mio vero codice:

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

Un po 'di codice 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);

Glück!


cosa succede se si desidera solo portare il pulsante 6 sopra l'immagine visualizzata e non gli altri pulsanti?
Adam Katz,

@AdamKatz: penso che tu debba riorganizzarli in un altro pugno di livello. Quindi, portalo sulla tua strada.
Giustino

grazie sto provando a portare solo un oggetto di una vista del riciclo sopra una vista ma lasciare gli altri oggetti sotto di esso, piuttosto bloccati!
Adam Katz

Ho usato lo stesso. Funziona bene con un solo problema che nasconde la barra degli strumenti.
user2980181

Funziona con più livelli? Diciamo che ho un ConstraintLayoutche contiene a RelativeLayout, e un altro RelativeLayout, entrambi hanno le stesse dimensioni di root ConstraintLayout( match_parent). Il primo RelativeLayoutha un Button, ed è anche dietro (ordine z) il secondo RelativeLayout. Posso fare Buttonin modo che il primo RelativeLayoutappaia come se fosse in cima a tutto, in modo che sia visibile e cliccabile, usando View::bringToFront()?
Oaskamay,


18

Prova FrameLayout, ti dà la possibilità di mettere le viste una sopra l'altra. Puoi crearne due LinearLayouts: una con le viste di sfondo e una con le viste di primo piano e combinarle usando il FrameLayout. Spero che questo ti aiuti.


1
Come possiamo portarlo in alto proprio come una finestra di dialogo?
Gaurav Arora,

@Infinity, puoi creare un FragmentDialog per questo scopo o semplicemente usare Theme.Dialog per la tua attività.
Egor,

Non posso usare FragmentDialog poiché è incompatibile con l'API 10. In secondo luogo, sto già usando un tema per la mia applicazione. C'è un altro modo? L'ho usato FrameLayout come hai detto tu!
Gaurav Arora,

@Infinity, È possibile utilizzare la versione della libreria di compatibilità di FragmentDialog, disponibile dall'API 4.
Egor,

8

Se stai usando ConstraintLayout, metti l'elemento dopo gli altri elementi per renderlo in primo piano rispetto agli altri



3

Può esserci un altro modo per salvare la giornata. Basta avviare una nuova finestra con il layout desiderato e mostrarla. Ne ho bisogno per mostrare un loadingView su un DialogFragment e questo è stato l'unico modo per riuscire.

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

bringToFront () potrebbe non funzionare in alcuni casi come il mio. Ma il contenuto del layout dialog_top deve sovrascrivere qualsiasi cosa sul livello dell'interfaccia utente. Ma comunque, questa è una brutta soluzione.


3

ho affrontato lo stesso problema. la seguente soluzione ha funzionato per me.

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

La seconda soluzione consiste nell'utilizzare xml aggiungendo questo attributo alla vista xml

android:translationZ=""

2

Puoi usare BindingAdapter in questo modo:

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


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

0

È necessario utilizzare il framelayout. E il modo migliore per farlo è rendere invisibile la vista quando non è richiesta. Inoltre è necessario impostare la posizione per ogni vista, in modo che si sposteranno in base alla posizione corrispondente


0

Se si utilizza un LinearLayoutsi dovrebbe chiamare myView.bringToFront()e dopo si dovrebbe chiamare parentView.requestLayout()e parentView.invalidate()per costringere il genitore a ridisegnare con il nuovo ordine bambino.


0

Prova a usare l'elevazione su di esso, qualcosa del genere yourview.setElevation(5);


0

Grazie all'utente Stack su questa spiegazione, ho funzionato anche su Android 4.1.1

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

Sul mio uso dinamico, per esempio, l'ho fatto

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

E Bamm!


-2

Disporli nell'ordine in cui si desidera mostrare. Supponiamo di voler mostrare la vista 1 nella parte superiore della vista 2. Quindi scrivere il codice vista 2 quindi scrivere il codice vista 1. Se non riesci a eseguire questo ordinamento, chiama bringToFront () nella vista principale del layout che vuoi portare in primo piano.


-32

È possibile impostare la visibilità su false di altre visualizzazioni.

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

o

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

e impostare

viewN.setVisibility(View.VISIBLE);

4
Ho bisogno che tutto sia visibile, non è questo il problema, il problema è l'ordine z. se la vitalità fosse il problema sarebbe facile da risolvere. . .
Lukap,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.