Jak przybliżyć wszystko?

134

Mam na niej aktywność i wiele widżetów, niektóre z nich mają animacje, a z powodu animacji niektóre widżety przesuwają się (tłumaczą) jeden nad drugim. Na przykład widok tekstu przesuwa się po niektórych przyciskach. . .

Chodzi o to, że chcę, aby guziki były zawsze z przodu. A kiedy widok tekstu się porusza, chcę przejść za przyciski.

Nie mogę tego osiągnąć. Próbowałem wszystkiego, co wiem, a metoda „bringToFront ()” zdecydowanie nie działa.

uwaga Nie chcę kontrolować kolejności z kolejności umieszczania elementu na layoucie, bo po prostu nie mogę :), układ jest złożony i nie mogę umieścić wszystkich przycisków na początku układu

Lukap
źródło
3
Użyłem RelativeLayoutz widokiem „z góry” występującym jako ostatni w XML. Zobacz stackoverflow.com/a/31340762/1121497
Ferran Maylinch
Czy ktoś może podać odpowiedni kod w formacie XML „bringToFront”
Shirish Herwade
1
Spróbuj użyć funkcji Elevation bottomView = Elevation: 1dp i topView = Elevation: 2dp w swoim xml || ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

Odpowiedzi:

147

Możesz wywołać bringToFront () w widoku, który chcesz uzyskać z przodu

To jest przykład:

    yourView.bringToFront();
Medo Elkamaly
źródło
4
Nieoczekiwany wynik: zastosowałem to w układzie pionowym liniowym i widok przeniesiony do przodu pojawił się na dole ... Na przykład miałem A / B / Ci chciałem wyprowadzić Ana wierzch, więc po uruchomieniu a.bringToFront()skończyłem z układem podobnym B / C / A.
Ferran Maylinch,
2
Więc znalazłem, że LinearLayoutnie można go używać z bringToFront. Skończyło się na użyciu RelativeLayout. Zobacz mój komentarz do samego pytania.
Ferran Maylinch
1
Czy ktoś może podać odpowiedni kod w formacie XML „bringToFront”
Shirish Herwade
Powoduje to zmianę położenia elementu, który przesuwam do przodu z dowolnego powodu. ViewCompat.setTranslationZ(view, 1)działa doskonale z drugiej strony.
Bimde
1
jeśli użyłem w manifeście android: theme = "@ android: style / Theme.Light.NoTitleBar" w aktywności niż yourView.bringToFront (); działa idealnie, ale użyłem androida: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); nie działa. Wszelkie wskazówki na ten temat.
Rahul
46

Przeglądałem przepełnienie stosu, aby znaleźć dobrą odpowiedź, a kiedy nie mogłem jej znaleźć, przejrzałem dokumenty.

Wydaje się, że nikt jeszcze nie natknął się na tę prostą odpowiedź:

ViewCompat.setTranslationZ(view, translationZ);

domyślne tłumaczenie z to 0.0

shrewdu
źródło
To jest położenie elementu na osi Z w px, znane również jako elewacja. setTranslationX przesunie widok wzdłuż osi X (w lewo / w prawo), setTranslationY wzdłuż osi Y (góra / dół). Oś Z jest trzecią osią.
xdevs23
O co chodzi setZ()? O ile dobrze pamiętam, pozycja Z widoku to w końcu jego elewacja plus jego translacja Z.
Gensoukyou1337
2
@ Gensoukyou1337, ViewCompat.setZ(view, yourValueInPixels); view.setZ()działa wtedy tylko na API 21 i nowszych.
Johnny Five
1
Sprawdzono kod Java 8 w Android Studio - sprawdza tylko, czy SDK_INT> = 21, więc dla <21 api nie ma żadnego efektu.
Vadim
37

Jeszcze prostszym rozwiązaniem jest edycja XML działania. Posługiwać się

android:translationZ=""
Toby
źródło
3
Jest to przydatne tylko w Android API 21 lub nowszym.
isakbob
30

Za pomocą tego kodu w XML

 android:translationZ="90dp"
Kryszna
źródło
3
Skąd się wziął 90dp?
Sudhir Khanger,
1
jest to wpis ręczny. Możesz spróbować w oparciu o swoje wymagania. 45 dp lub 135 dp lub 180 dp lub 270 dp
Krishna
1
Nie możesz po prostu użyć 1dp?
Tyler Turnbull
1
wymagane API 21+
Muhammad Saqib
25

bringToFront()jest właściwą drogą, ale PAMIĘTAJ, że musisz wywołać bringToFront()i wykonać invalidate()metodę w widoku najwyższego poziomu (w widoku głównym), np .:

Twoja hierarchia widoku to:

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

Tak więc, gdy animujesz z powrotem swoje przyciski (1-> 6), twoje przyciski będą pod (poniżej) ImageView. Aby to zmienić (powyżej) ImageView, musisz wywołać bringToFront()i invalidate()metodę na swoim LinearLayouts. Wtedy to zadziała :) ** UWAGA: Pamiętaj, aby ustawić android:clipChildren="false"dla układu głównego lub gradparent_layout animate-view. Rzućmy okiem na mój prawdziwy kod:

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

Trochę kodu w .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);

GLuck!

Justin
źródło
co jeśli chcesz umieścić tylko przycisk 6 nad widokiem obrazu, a nie inne przyciski?
Adam Katz
@AdamKatz: Myślę, że musisz ponownie zorganizować je w pięść innego poziomu. Następnie przynieś to sobie w drodze.
Justin
dzięki Próbuję umieścić tylko jeden element widoku recyklera nad widokiem, ale pozostałe elementy pozostawiam pod nim, całkiem zablokowany!
Adam Katz
Użyłem tego samego. Działa dobrze z jednym problemem, że ukrywa pasek narzędzi.
user2980181
Czy to działa na wielu poziomach? Powiedzmy, że mam a, ConstraintLayoutktóry zawiera a RelativeLayout, a inny RelativeLayout, oba mają ten sam rozmiar co jego root ConstraintLayout( match_parent). Pierwsza RelativeLayoutma a Button, a także jest za (w kolejności z) drugą RelativeLayout. Czy mogę sprawić, aby Buttonpierwszy RelativeLayoutwyglądał tak, jakby znajdował się nad wszystkim, tak, aby był widoczny i klikalny, używając View::bringToFront()?
oaskamay,
18

Spróbuj FrameLayout, daje możliwość umieszczenia widoków jeden na drugim. Możesz utworzyć dwa LinearLayouts: jeden z widokami w tle i jeden z widokami pierwszego planu i połączyć je za pomocą FrameLayout. Mam nadzieję że to pomoże.

Egor
źródło
1
Jak możemy go przenieść na górę, tak jak dialog?
Gaurav Arora
@Infinity, możesz w tym celu utworzyć FragmentDialog lub po prostu użyć Theme.Dialog do swojego działania.
Egor
Nie mogę używać FragmentDialog, ponieważ jest niezgodny z API 10. Po drugie, używam już motywu dla mojej aplikacji. Czy jest inny sposób? Użyłem go FrameLayout, tak jak powiedziałeś!
Gaurav Arora
@Infinity, możesz użyć wersji biblioteki zgodności FragmentDialog, która jest dostępna w API 4.
Egor
9

Jeśli używasz ConstraintLayout, po prostu umieść element po innych elementach, aby był z przodu niż pozostałe

Fajar Ulin Nuha
źródło
5

Możesz spróbować użyć bringChildToFront, możesz sprawdzić, czy ta dokumentacja jest pomocna na stronie Android Developers .

Emanuel
źródło
4

stanąłem przed tym samym problemem. poniższe rozwiązanie zadziałało dla mnie.

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

Drugim rozwiązaniem jest użycie kodu XML i dodanie tego atrybutu do pliku XML widoku

android:translationZ=""
Mudassir Khan
źródło
3

Może być inny sposób na uratowanie dnia. Po prostu zainicjuj nowe okno dialogowe z żądanym układem i po prostu je pokaż. Potrzebuję go do wyświetlania loadingView przez DialogFragment i był to jedyny sposób, w jaki mi się udało.

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

bringToFront () może nie działać w niektórych przypadkach, takich jak mój. Ale zawartość układu dialog_top musi przesłonić wszystko w warstwie interfejsu użytkownika. Ale w każdym razie jest to brzydkie obejście.

asozcan
źródło
2

Możesz użyć BindingAdapter w następujący sposób:

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


  <ImageView
        ...
        app:bringToFront="@{true}"/>
Ahmad Aghazadeh
źródło
0

Musisz użyć framelayout. A lepszym sposobem na to jest uczynienie widoku niewidocznym, gdy nie jest to potrzebne. Musisz także ustawić pozycję dla każdego widoku, aby poruszały się zgodnie z odpowiednią pozycją

Ranjit Mishra
źródło
0

Jeśli używasz a LinearLayout, powinieneś zadzwonić, myView.bringToFront()a potem zadzwonić parentView.requestLayout()i parentView.invalidate()zmusić rodzica do przerysowania z nowym zamówieniem podrzędnym.

Cristian
źródło
0

Dzięki użytkownikowi Stack nad tym wyjaśnieniem, mam to działające nawet na Androidzie 4.1.1

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

Na przykład podczas mojego dynamicznego użytkowania tak

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

I Bamm!

PYK
źródło
-2

Ułóż je w kolejności, w jakiej chcesz je pokazać. Załóżmy, że chcesz wyświetlić widok 1 na widoku 2. Następnie napisz kod widoku 2, a następnie napisz kod widoku 1. Jeśli nie możesz wykonać tej kolejności, wywołaj bringToFront () do głównego widoku układu, który chcesz umieścić na wierzchu.

Shuvendu Dhal
źródło
-32

Widoczność innych widoków można ustawić na wartość false.

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

lub

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

i nastaw

viewN.setVisibility(View.VISIBLE);
toozowy
źródło
4
Potrzebuję, żeby wszystko było widoczne, to nie jest problem, problem jest w porządku z. gdyby problemem była żywotność, byłoby to łatwe do rozwiązania. . .
Lukap,