Definiowanie kolejności widoków RelativeLayout w systemie Android


226

Chciałbym zdefiniować kolejność Z widoków RelativeLayout w Androidzie.

Wiem, że jednym ze sposobów jest dzwonienie bringToFront.

Czy jest na to lepszy sposób? Byłoby wspaniale, gdybym mógł zdefiniować kolejność Z w xml układu.


4
View.bringToFront (); jest anser
Shirish Herwade

Odpowiedzi:


314

Najprostszym sposobem jest zwrócenie uwagi na kolejność dodawania widoków do pliku XML. Niższe w pliku oznacza wyżej w osi Z.

Edycja: jest to udokumentowane tu i tutaj na stronie programisty Androida. (Dzięki @flightplanner)


16
Niestety nie zawsze można to zmienić. Na przykład w układzie względnym każdy element może być rozłożony tylko w stosunku do elementów uprzednio zdefiniowanych w pliku
Casebash

67
Casebash, nie sądzę, że w takim przypadku koniecznie trzeba użyć „@ + id / your_element_before_its_defined”, a następnie użyć tego samego identyfikatora w elemencie, który zdefiniujesz później. Mogę się mylić, te układy są dla mnie bardzo trudne, ale zdecydowanie mam wrażenie, że to działa.
tjb

7
tjb ma rację (i cieszę się, że ma). Użyj @ + id z pierwszą wzmianką o id, np. Layout_above = "@ + id / some_id"
Michiel,

3
Możesz również umieścić <item type = "id" name = "<yout_id>" /> w pliku XML wartości, a następnie możesz odwoływać się do niego w dowolnym miejscu.
karl

8
Wiem, że spóźniłem się na imprezę około 3 lat, ale w odpowiedzi na @hpique jest to udokumentowane tutaj
HexAndBugs


68

Uwaga: przyciski i inne elementy w API 21 i nowszych mają wysokie rzędne, dlatego ignorują kolejność elementów w xml bez względu na układ nadrzędny. Zajęło mi trochę czasu, żeby to rozgryźć.


16
rozwiązaniem tego błędu było dla mnie wywołanie setElevation (1000) w widoku, który chcę wyświetlić za pomocą przycisku.
strzelić do dołka

setElevation () wymaga interfejsu API poziomu 21
dp2050

21

W systemie Android, począwszy od interfejsu API poziomu 21, elementy w pliku układu uzyskują swoją kolejność Z zarówno od sposobu, w jaki są uporządkowane w pliku, jak opisano w prawidłowej odpowiedzi, a od ich rzędnej wyższa wartość rzędnej oznacza, że ​​element otrzymuje wyższą kolejność Z .

Może to czasem powodować problemy, szczególnie w przypadku przycisków, które często pojawiają się nad elementami, które zgodnie z kolejnością XML powinny znajdować się poniżej nich w kolejności Z. Aby to naprawić, po prostu ustaw android:elevationelementy w swoim układzie XML, aby pasowały do ​​kolejności Z, którą chcesz osiągnąć.

Jeśli ustawisz rzędną elementu w układzie, zacznie on rzucać cień. Jeśli nie chcesz tego efektu, możesz usunąć cień za pomocą kodu:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   myView.setOutlineProvider(null);
}

Nie znalazłem żadnego sposobu na usunięcie cienia podwyższonego widoku przez xml układu.


1
Jak wspomniano w komentarzach, możesz użyć android:elevation="1000dp". W ten sposób nie jest renderowany cień.
Vadim Kotov

15

Napotkałem te same problemy: w układzie względnym parentView mam 2 dzieci childView1 i childView2. Na początku umieszczam childView1 nad childView2 i chcę, aby childView1 był na szczycie childView2. Zmiana kolejności widoków dzieci nie rozwiązała problemu. Dla mnie zadziałało ustawienie androida: clipChildren = "false" na parentView oraz w ustawionym przeze mnie kodzie:

childView1.bringToFront();

parentView.invalidate();

2
To działa, a Android bardzo mnie zasmuca. child.bringToFront()z parent.invalidate()uczynków, ale parent.bringChildToFront(child)tego nie robi. Gdzie jest logika, której wszyscy oczekujemy od systemu operacyjnego?
Oliver Hausler

Aby animować niektóre widoki (tłumaczenia w X i Y), wypróbowałem kilka kombinacji dla LinearLayout, FrameLayout i RelativeLayout, ale zawsze występowały problemy (związane z nakładaniem się lub nieproporcjonalnymi rozmiarami). Wreszcie android:clipChildren="false"załatwił sprawę. Dziękuję Ci!
JCarlosR

15

Pamiętaj, że możesz używać, view.setZ(float)zaczynając od poziomu API 21. Tutaj znajdziesz więcej informacji.


13

Myślałem, że dodam odpowiedź od czasu wprowadzenia

Android: translationZ

Pole XML zmieniło to trochę. Inne odpowiedzi sugerujące uruchomienie

childView1.bringToFront();

parentView.invalidate();

są całkowicie WYJĄTKOWE, ponieważ ten kod NIE spowoduje wyświetlenia childView1 przed jakimkolwiek widokiem za pomocą wbudowanego Androida: translationZ w pliku XML. Miałem z tym problemy i kiedy usunąłem to pole z innych widoków, bringToFront () działało dobrze.


dotyczy to również Androida 5elevation
shelll

5

API 21 ma view.setElevation(float)wbudowane

Użyj ViewCompat.setElevation(view, float);dla kompatybilności wstecznej

Więcej metod ViewCompat.setZ(v, pixels)iViewCompat.setTranslationZ(v, pixels)

Innym sposobem jest zbieranie przycisków lub wyświetlanie tablicy i używanie ich addViewdo dodawania do RelativeLayout




0

Sprawdź, czy masz jakąkolwiek rzędną w jednym z widoków w XML. Jeśli tak, dodaj elewację do drugiego elementu lub usuń elewację, aby rozwiązać problem. Stamtąd kolejność poglądów decyduje o tym, co stoi ponad innymi.


0

Lub umieść nakładający się przycisk lub widoki wewnątrz FrameLayout. Następnie RelativeLayout w pliku xml będzie przestrzegać kolejności układów potomnych podczas dodawania.


0

Możesz użyć poniższego kodu również do osiągnięcia tego samego

ViewCompat.setElevation(sourceView, ViewCompat.getElevation(mCardView)+1);

Jest to kompatybilne wstecz. Oto mCardViewwidok, który powinien być poniżej sourceView.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.