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.