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


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

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


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=""

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!


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"

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.


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



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.


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=""

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}"/>

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


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.


0

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


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!


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


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

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.