Wie kann man die Sicht vor alles bringen?

130

Ich habe Aktivität und viele Widgets drauf, einige von ihnen haben Animationen und aufgrund der Animationen bewegen sich einige der Widgets übereinander. Beispielsweise bewegt sich die Textansicht über einige Schaltflächen. . .

Jetzt möchte ich, dass die Tasten immer vorne sind. Und wenn sich die Textansicht bewegt, möchte ich mich hinter die Schaltflächen bewegen.

Ich kann das nicht erreichen. Ich habe alles versucht, was ich weiß, und "bringToFront ()" funktioniert definitiv nicht.

Hinweis Ich möchte die Z-Reihenfolge nicht durch die Reihenfolge der Platzierung des Elements im Layout steuern, da ich dies einfach nicht kann :), das Layout ist komplex und ich kann nicht alle Schaltflächen am Anfang des Layouts platzieren

Lukap
quelle
3
Ich habe eine RelativeLayoutmit der "Draufsicht" verwendet, die zuletzt im XML angezeigt wird. Siehe stackoverflow.com/a/31340762/1121497
Ferran Maylinch
Kann jemand bitte den entsprechenden Code in XML von 'bringToFront'
Shirish Herwade
Versuchen Sie, die Höhe bottomView = Höhe: 1dp und topView = Höhe: 2dp in Ihrer XML || zu verwenden ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

Antworten:

144

Sie können bringToFront () für die Ansicht aufrufen, die Sie vorne erhalten möchten

Dies ist ein Beispiel:

    yourView.bringToFront();
Medo Elkamaly
quelle
4
Unerwartetes Ergebnis: Ich habe das in einem vertikalen linearen Layout verwendet und die nach vorne gerichtete Ansicht wurde unten angezeigt ... Zum Beispiel hatte A / B / Cund wollte ich Anach vorne bringen, also kam a.bringToFront()ich nach dem Laufen zu einem Layout wie B / C / A.
Ferran Maylinch
2
Also fand ich LinearLayoutnicht kann mit verwendet werden bringToFront. Am Ende habe ich ein RelativeLayout. Siehe meinen Kommentar zur Frage selbst.
Ferran Maylinch
1
Kann jemand bitte den entsprechenden Code in XML von 'bringToFront'
Shirish Herwade
Dies führt zu einer Neupositionierung des Elements, das ich aus irgendeinem Grund nach vorne bewege. ViewCompat.setTranslationZ(view, 1)funktioniert andererseits perfekt.
Bimde
1
wenn ich in Manifest android verwendet habe: theme = "@ android: style / Theme.Light.NoTitleBar" in Aktivität als yourView.bringToFront (); funktioniert perfekt, aber ich habe android verwendet: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); funktioniert nicht Irgendein Hinweis darauf.
Rahul
41

Ich habe den Stapelüberlauf durchgesehen, um eine gute Antwort zu finden, und als ich keine finden konnte, habe ich die Dokumente durchgesehen.

Noch scheint niemand über diese einfache Antwort gestolpert zu sein:

ViewCompat.setTranslationZ(view, translationZ);

Standardübersetzung z ist 0.0

Spitzmaus
quelle
Dies ist die Position des Elements auf der Z-Achse in px, auch als Elevation bezeichnet. setTranslationX verschiebt die Ansicht entlang der X-Achse (links / rechts), setTranslationY entlang der Y-Achse (oben / unten). Die Z-Achse ist die 3. Achse.
Xdevs23
Was ist mit setZ()? Wenn ich mich richtig erinnere, ist die Z-Position der Ansicht schließlich ihre Höhe plus ihre Übersetzung Z.
Gensoukyou1337
2
@ Gensoukyou1337, ViewCompat.setZ(view, yourValueInPixels); view.setZ()funktioniert dann nur auf API 21 und höher.
Johnny Five
1
Überprüfter Java 8-Code in Android Studio - prüft nur, ob SDK_INT> = 21 ist, sodass er für <21 API keine Auswirkung hat.
Vadim
32

Eine noch einfachere Lösung besteht darin, das XML der Aktivität zu bearbeiten. Verwenden

android:translationZ=""
Toby
quelle
3
Dies ist nur in Android API 21 oder höher nützlich.
Isakbob
25

bringToFront()Dies ist der richtige Weg. Beachten Sie jedoch, dass Sie die Methode auf höchster Ebene (unter Ihrer Stammansicht) aufrufen bringToFront()und invalidate()methodisieren müssen , z.

Die Hierarchie Ihrer Ansicht lautet:

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

Wenn Sie also Ihre Schaltflächen (1-> 6) wieder animieren, werden Ihre Schaltflächen unter (unter) dem angezeigt ImageView. Um es über (oben) zu bringen, ImageViewmüssen Sie auf Ihrem s aufrufen bringToFront()und invalidate()methodisieren LinearLayout. Dann wird es funktionieren :) ** HINWEIS: Denken Sie daran, android:clipChildren="false"für Ihr Root-Layout oder das gradparent_layout der Animationsansicht festzulegen. Werfen wir einen Blick auf meinen echten 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>

Etwas 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);

Glück!

Justin
quelle
Was ist, wenn Sie nur die Schaltfläche 6 über der Bildansicht und nicht die anderen Schaltflächen platzieren möchten?
Adam Katz
@AdamKatz: Ich denke, du musst sie in einer anderen Ebene neu organisieren. Dann bring es dir in den Weg.
Justin
danke Ich versuche nur ein Element einer Recycler-Ansicht über eine Ansicht zu bringen, lasse aber die anderen Elemente darunter, ziemlich fest!
Adam Katz
Ich habe das gleiche benutzt. Es funktioniert gut mit einem einzigen Problem, dass es die Symbolleiste verbirgt.
user2980181
Funktioniert das mit mehreren Ebenen? Nehmen wir an, ich habe eine ConstraintLayout, die a enthält RelativeLayout, und eine andere RelativeLayout, beide haben die gleiche Größe wie root ConstraintLayout( match_parent). Der erste RelativeLayouthat ein Buttonund liegt auch hinter dem zweiten (z-Reihenfolge) RelativeLayout. Kann ich das Buttonim ersten RelativeLayoutso erscheinen lassen, als ob es über allem wäre, so dass es sichtbar und anklickbar ist View::bringToFront()?
Oaskamay
25

Mit diesem Code in XML

 android:translationZ="90dp"
Krishna
quelle
3
Woher kam 90dpes?
Sudhir Khanger
1
Es ist eine manuelle Eingabe. Sie können es je nach Ihren Anforderungen versuchen. entweder 45dp oder 135dp oder 180dp oder 270dp
Krishna
Könnten Sie nicht einfach 1dp verwenden?
Tyler Turnbull
18

Versuchen Sie FrameLayout, es gibt Ihnen die Möglichkeit, Ansichten übereinander zu setzen. Sie können zwei erstellen LinearLayouts: eine mit den Hintergrundansichten und eine mit Vordergrundansichten, und diese mit der kombinieren FrameLayout. Hoffe das hilft.

Egor
quelle
1
Wie können wir es wie einen Dialog nach oben bringen?
Gaurav Arora
@Infinity, Sie können zu diesem Zweck einen FragmentDialog erstellen oder einfach den Theme.Dialog für Ihre Aktivität verwenden.
Egor
Ich kann FragmentDialog nicht verwenden, da es für API 10 nicht kompatibel ist. Zweitens verwende ich bereits ein Thema für meine Anwendung. Gibt es einen anderen Weg? Ich habe es FrameLayout verwendet, genau wie du gesagt hast!
Gaurav Arora
@Infinity, Sie können die Kompatibilitätsbibliotheksversion von FragmentDialog verwenden, die von API 4 verfügbar ist.
Egor
8

Wenn Sie verwenden ConstraintLayout, setzen Sie das Element einfach hinter die anderen Elemente, um es vor die anderen zu stellen

Fajar Ulin Nuha
quelle
3

Es kann einen anderen Weg geben, der den Tag rettet. Initiieren Sie einfach einen neuen Dialog mit dem gewünschten Layout und zeigen Sie ihn einfach an. Ich brauche es, um eine Ladeansicht über ein DialogFragment anzuzeigen, und nur so war ich erfolgreich.

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

bringToFront () funktioniert in einigen Fällen wie meinem möglicherweise nicht. Der Inhalt des dialog_top-Layouts muss jedoch alles auf der UI-Ebene überschreiben. Dies ist jedoch eine hässliche Problemumgehung.

Asozcan
quelle
3

Ich habe das gleiche Problem konfrontiert. Die folgende Lösung hat bei mir funktioniert.

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

Die zweite Lösung besteht darin, xml zu verwenden und dieses Attribut der Ansicht xml hinzuzufügen

android:translationZ=""
Mudassir Khan
quelle
2

Sie können BindingAdapter folgendermaßen verwenden:

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


  <ImageView
        ...
        app:bringToFront="@{true}"/>
Ahmad Aghazadeh
quelle
0

Sie müssen Framelayout verwenden. Und der bessere Weg, dies zu tun, besteht darin, die Ansicht unsichtbar zu machen, wenn sie nicht benötigt werden. Außerdem müssen Sie die Position für jede Ansicht festlegen, damit sie sich entsprechend der entsprechenden Position bewegen

Ranjit Mishra
quelle
0

Wenn Sie ein verwenden LinearLayout, sollten Sie anrufen myView.bringToFront()und danach anrufen parentView.requestLayout()und parentView.invalidate()den Elternteil zwingen, mit der neuen untergeordneten Reihenfolge neu zu zeichnen.

Cristian
quelle
0

Versuchen Sie, die Höhe darauf zu verwenden, so etwas wie yourview.setElevation(5);

Amitoj
quelle
0

Dank des Stack- Benutzers über diese Erklärung funktioniert dies sogar unter Android 4.1.1

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

Bei meiner dynamischen Nutzung habe ich das zum Beispiel getan

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

Und Bamm!

PYK
quelle
-2

Ordnen Sie sie in der Reihenfolge an, die Sie anzeigen möchten. Angenommen, Sie möchten Ansicht 1 über Ansicht 2 anzeigen. Schreiben Sie dann Code für Ansicht 2 und dann Code für Ansicht 1. Wenn Sie diese Bestellung nicht ausführen können, rufen Sie bringToFront () in der Stammansicht des Layouts auf, das Sie vorlegen möchten.

Shuvendu Dhal
quelle
-32

Sie können die Sichtbarkeit anderer Ansichten auf false setzen.

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

oder

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

und setzen

viewN.setVisibility(View.VISIBLE);
thenosic
quelle
4
Ich brauche, dass alles sichtbar ist, das ist nicht das Problem, das Problem ist die Z-Reihenfolge. Wenn Lebensfähigkeit das Problem wäre, wäre es zu einfach zu lösen. . .
Lukap