2015-11-23 11 views
12

Napisałem dwa numery ItemDecorator dla RecyclerView. Każdy dodaje trochę przesunięcia górnego w getItemOffsets(). Powiedzmy:Jak uzyskać przesunięcie w RecyclerView ItemDecorator

  • Pierwszy dekorator dodaje 20dp top przesunięcie
  • drugie decrator dodaje 30dp top przesunięcie

Teraz, kiedy dodać oboje do RecyclerView, każdy element jest prawidłowo offsetted przez 50dp, to dobry.

Ale tutaj pojawia się pytanie: Jak uzyskać to przesunięcie w onDraw/onDrawOver?

Zazwyczaj dekoratorzy rysują swoje rzeczy, przechodząc parent.getChildAt(i) rzeczy i otrzymując child.getTop() na przykład, aby narysować powyżej widoku dziecka RecyclerView.

Ale w takim przypadku pomieszałoby się rysunek innego dekoratora, ponieważ użyłoby ono również child.getTop().

W tej chwili wydaje się, że obaj dekoratorzy muszą wiedzieć o sobie nawzajem io wzajemnej wysokości.

Czy tu czegoś brakuje? Mam nadzieję, że jestem.

EDYTOWANIE:Zgłosiłem problem do narzędzia do śledzenia problemów z systemem Android i wygląda na to, że będzie ono działać. Oznacz go, aby śledzić postęp:https://code.google.com/p/android/issues/detail?id=195746

Odpowiedz

12

tl; dr Nie niczego nie brakuje. Ale możesz uzyskać wartości potrzebne w getItemOffsets, choć wydaje mi się to trochę brudne.

Zasadniczo istnieje tylko jeden opcja uzyskiwania urządzone wysokości innej niż zarządzanie ozdoby siebie: LayoutManager.getDecoratedTop();

OnDraw

W onDraw można dostać cały obszar roboczy o recyclerView, c.getClipBounds() nie posiada jakakolwiek informacja. Mimo że javadoc dodawania dekoracji mówi, że dekoracje powinny tylko rysować z ich granicami.

Również uzyskanie parent.getLayoutManager().getDecoratedTop() da takie same wartości w każdym zdobieniu, ponieważ jest już za późno, te wartości służą do celów układania.

Jesteśmy już za późno, układanie jest zrobione i przegapiliśmy to.

getItemOffsets

Należy pamiętać, że badane następujące z LinearLayoutManager i to może nie tak dobrze współpracować z innymi (zdecydowanie nie z większością tych niestandardowych). Ponieważ polegam na pomiarze zdarzających się między tymi połączeniami, które nie są udokumentowane, dane rozwiązanie może zepsuć się z pewną przyszłą wersją.

Po prostu czułem, że potrzebuję tego zrzeczenia się odpowiedzialności. Znalazłem roztwór roboczy (oglądać mOffset):

@Override 
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { 
    mOffset = parent.getLayoutManager().getTopDecorationHeight(view); 
    outRect.set(0, 10, 0, 0); 
} 

To działa, ponieważ recyclerview, przy obliczaniu całkowitej wstawka dziecka, jest updating the views package local LayoutParams variable. Chociaż nie możemy uzyskać dostępu do samej zmiennej parametru layout, wywołanie getTopDecorationHeight w rzeczywistości używa (obecnie) brudnej wstawki, dając nam właściwą wartość.
W związku z tym można uzyskać przesunięcie poprzednich dekoracji przed zastosowaniem własnego!

Aby zastosować go po prostu usunąć pozostałe ozdoby offsetu przy opracowywaniu swojej dekoracji:

c.drawRect(child.getLeft() + child.getTranslationX(), 
     mOffset + layoutManager.getDecoratedTop(child) + child.getTranslationY(), 
     child.getRight() + child.getTranslationX(), 
     child.getBottom() + child.getTranslationY(), paint); 

To rzeczywiście obowiązują inne dekoracje offset, następnie wyciągnąć własne z prawidłowego górze.

pewne problemy

Jest to obecnie podstawowe, roztwór roboczy dla domyślnego USECASE. ALE. Jeśli masz różne przesunięcia w zależności od pozycji VIEW_TYPE lub pozycji adaptera, sytuacja staje się trudna.

Powielenie logiki i zachowanie różnych przesunięć dla różnych typów widoku lub zapisanie/pobranie przesunięcia dla każdego widoku lub widoku.

Aby to zrobić, można dodać niestandardowy znacznik za pomocą view.setTag(key, object) lub zrobić coś podobnego do obiektu RecyclerView.State, który jest przekazywany.

+0

Dziękuję za szczegółową odpowiedź! Na razie tak będzie, chociaż muszę dodać, że obecna sytuacja nie jest zbyt dobra. Muszę znaleźć czas, aby zgłosić problem związany z tym narzędziem do śledzenia błędów Androida. – dimsuz

+1

@dimsuz Czuję się naprawdę dobrze z obecnym rozwiązaniem i myślę, że może działać. jeśli zadasz problem, proszę podaj link! dzięki :) –

+1

Zgłoszono: https://code.google.com/p/android/issues/detail?id=195746 – dimsuz

Powiązane problemy