8

To jest bardziej ogólne pytanie, ale po wielu poszukiwaniach i próbie nie jestem w stanie zrozumieć, dlaczego tak trudno jest to osiągnąć. This to najbliższa odpowiedź, którą mogę znaleźć, ale wciąż nie mogę jej wdrożyć.Jak sprawić, by RecyclerView przewijał się płynnie?

Aby być konkretnym używam RecyclerView z GridLayoutManager. Wszystko czego chcę, to układ siatki do płynnego przewijania (jak domyślna aplikacja galwaniczna), nic nadzwyczajnego, ale domyślna implementacja menedżera układu siatki przewija widok w sposób "zgryźliwy". Próbowałem zaimplementować metodę z powyższego linku, ale bezskutecznie.

Próbowałem również wdrożyć LinearSmoothScroller, ale nie jestem pewien, jak wdrożyć metodę computeScrollVectorForPosition. Google's documentation na computeScrollVectorForPosition dosłownie ma 0 słów.

Znalazłem this 3 part tutorial, ale było to bardzo mało pomocne. Pytam tylko: czy istnieje jakiś szablon kodu, który możemy zastosować w LinearSmoothScroller lub rozszerzając RecyclerView.SmoothScroller i uzyskując płynne przewijanie? Nawet jeśli kod zależy od liczby przedmiotów i przedmiotów w wierszu w gridlayout, musi być jakaś metoda, aby to zrobić łatwo. Czy coś mi umyka ?

+0

- może powinieneś określić, dlaczego twój istniejący kod jest "szarpany", używając narzędzi takich jak Traceview, 'StrictMode' i tak dalej. – CommonsWare

+0

@commonsWare Więc masz na myśli domyślną implementację GridLayoutManager powinna płynnie przewijać gridview? Przykro mi, jeśli zabrzmię noob, jestem całkiem nowy w Android Programming. – rockfight

+4

"Czyli domyślna implementacja GridLayoutManager powinna płynnie przewijać gridview?" - tak, przynajmniej dla mojej definicji "sprawnie". Typowym źródłem "szarpanego" przewijania w Androidzie jest zbyt długa aplikacja na głównym wątku aplikacji aktualizującym interfejs użytkownika. W przypadku 'RecyclerView', oznaczałoby to zajęcie zbyt dużej ilości czasu w' onBindViewHolder() 'lub ewentualnie w' onCreateViewHolder() '. Każdy z nich musi powrócić w czasie poniżej milisekund, co oznacza, że ​​nie można w nim wykonać operacji we/wy dysku lub sieciowych operacji we/wy. – CommonsWare

Odpowiedz

28

Typowym źródłem "szarpanego" przewijania w Androidzie jest zbyt długa aplikacja na głównym wątku aplikacji aktualizującym interfejs użytkownika. W przypadku RecyclerView oznaczałoby to zajęcie zbyt dużej ilości czasu w onBindViewHolder() lub ewentualnie w onCreateViewHolder(). Każdy z nich musi powrócić w czasie poniżej milisekund, co oznacza, że ​​nie można w nim wykonać operacji we/wy dysku lub sieciowych operacji we/wy.

Myślę, że znalazłem problem. Używam holder.photo.setImageBitmap (BitmapFactory.decodeFile (itemList.get (position) .get AbsolutePath())); on onBindViewHolder(), a plik obrazu ma rozmiar około 100kb, z kilkoma obrazami z listy

Tak, to będzie robić dysk I/O i dekodowanie obrazu w głównym wątku aplikacji. To będzie wystarczająco powolne, aby spowodować jank w interfejsie użytkownika (to jest "szarpane" przewijanie).

Należy rozważyć użycie biblioteki ładującej obraz, takiej jak Picasso lub Universal Image Loader, ponieważ mogą one asynchronicznie zapełniać bitmapę swojej ImageView.

This sample app używa uniwersalnej ładowarki obrazu, aby pomóc wypełnić zawartość RecyclerView (z GridLayoutManager), ze źródłem dane są dostępne filmy na urządzeniu.

+0

Dziękuję, sprawdzę je i wdrożę. W międzyczasie, jak przy użyciu tego (http://developer.android.com/training/displaying-bitmaps/load-bitmap.html) prostego rozwiązania zamiast korzystania z oddzielnej biblioteki? – rockfight

+0

@rockfight: Ponieważ ma to niewiele wspólnego z twoim problemem. Głównym celem tej strony jest wydajność pamięci, a nie główny czas wątku aplikacji. – CommonsWare

+0

UIL nie działa, gdy obraz znajduje się na karcie SD (ścieżka pliku zaczyna się od '/ storage' Użyłem' Glide' do tego celu, i stanowiło idealne rozwiązanie mojego problemu – Rajat

-1

prostu dodać ten

animateLayoutChanges = true 

w recyclerview xml

+2

więc co to jest? –

1
android:animateLayoutChanges="false" 
+2

więc co to jest? –

12

Dodaj to gdziekolwiek zadeklarowały recyclerview w swojej działalności lub fragment

RecyclerView mRecyclerview = (RecyclerView) findViewById(...); 
mRecyclerview.setNestedScrollingEnabled(false); 

setNestedScrollview (fałsz) działa dla Ciebie.

0

Właśnie napotkałem ten problem, a wyłączenie zagnieżdżonego przewijania go poprawił. Czy to tak:

yourRecyclerview.setNestedScrollingEnabled(false); 

Albo można zmienić wartości w pliku xml, w którym zdefiniowane RecyclerView: „Czy ja czegoś brakuje tutaj”

<android.support.v7.widget.RecyclerView 
    android:id="@+id/yourRecyclerView" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:nestedScrollingEnabled="false"/> 
Powiązane problemy