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


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

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


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

3
Jest to przydatne tylko w Android API 21 lub nowszym.
isakbob


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!


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.


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



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

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.


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

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ą


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.


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!


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


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

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