2017-12-16 132 views
7

Używam szybkiego przewijania domyślnego RecyclerView, a ja podążam za this guide, aby go obsłużyć.RecyclerView Szybka przewiń wysokość kciuka za mała dla dużego zestawu danych

Problem polega na tym, że kciuk zmienia swoją wysokość zgodnie z rozmiarem zestawu danych. W przypadku dużych przedmiotów, takich jak 100 i powyżej, kciuk staje się bardzo mały i prawie trudno jest odpowiedzieć na przeciąganie.

Czy mogę ustawić minimalną wysokość kciuka szybkiego przewijania?

+2

Ten sam problem w mojej aplikacji. Czy możemy zdefiniować kciuk poprawkowy, który nie zmniejsza się w zależności od rozmiaru listy? – egmontr

+1

Ten sam problem w mojej aplikacji –

+0

Powyższa odpowiedź jest bardzo ograniczona. Oto przykład (https://bitbucket.org/StylingAndroid/scrollingrecyclerview/src/2fc7d871b911144b492744bb3a5097bb01869ac1?at=Part1) tego, co chcesz zrobić. –

Odpowiedz

3

To tylko częściowa odpowiedź; Brakuje mi (przynajmniej) jednego kawałka układanki, ale mam nadzieję, że ktoś inny to wymyśli.

Po dodaniu niezbędne atrybuty tagu <RecyclerView> (jak wspomniano w odpowiedzi związanej z pytaniem OP), wymiarowania/pozycjonowanie kciuka paska przewijania jest kontrolowana przez trzech metod wewnątrz LinearLayoutManager:

  • int computeVerticalScrollRange(): Rozmiar ścieżki paska przewijania.

  • int computeVerticalScrollExtent(): Wielkość kciuka paska przewijania.

  • int computeVerticalScrollOffset(): Odległość między górną częścią ścieżki paska przewijania i górną częścią kciuka paska przewijania.

Jednostki dla tych metod są arbitralne; możesz używać wszystkiego, co chcesz, o ile wszystkie trzy metody dzielą te same jednostki. Domyślnie LinearLayoutManager będzie użyć jednego z dwóch zestawów jednostek:

  • mSmoothScrollbarEnabled == true: używać jednostek w oparciu o wielkości piksela widocznych elementów w RecyclerView.

  • mSmoothScrollbarEnabled == false: Użyj jednostek na podstawie pozycji widocznych elementów w adapterze RecyclerView.

Aby kontrolować wielkość kciuka pasek przewijania za siebie, będziesz musiał zastąpić te metody ... ale oto kawałek mi brakuje: We wszystkich moich eksperymentów, computeVerticalScrollExtent() nigdy nie jest wywoływana przez system. To powiedziawszy, nadal możemy pokazać tutaj pewien postęp.

Najpierw utworzyłem prosty adapter, który pokazuje 500 CardView s z pozycją przedmiotu w środku. Włączam szybkie przewijanie za pomocą naprawdę prostych (ale brzydkich) rysunków. Oto co przewijania wygląda tylko z realizacji domyślny LinearLayoutManager:

enter image description here

Jak już stwierdzono, 500 (małych) przedmiotów, kciuk przewijania jest bardzo mały i bardzo ciężko dotknąć. Możemy uczynić pasek przewijania znacznie większym przez przesłonięcie computeVerticalScrollRange(), aby zwrócić stałą stałą ...Wybrałem 5000 zasadniczo losowo tylko pokazać istotną zmianę:

enter image description here

Oczywiście, teraz pasek przewijania nie działa jak można się spodziewać; przewijanie listy przez przeciąganie jej w normalny sposób przesuwa kciuk o wiele bardziej niż powinien, a szybkie przewijanie listy przeciągając kciuk przesuwa listę o wiele mniej niż powinna.

na urządzeniu, z losowo wybranego zakresu 5000, nadrzędnymi computeVerticalScrollOffset() następująco czyni kciuk przewijania poruszać doskonale jak przewijać listę przeciągając na niego:

@Override 
public int computeVerticalScrollRange(RecyclerView.State state) { 
    return 5000; 
} 

@Override 
public int computeVerticalScrollOffset(RecyclerView.State state) { 
    return (int) (super.computeVerticalScrollOffset(state)/23.5f); 
} 

Jednak to nadal nie robi” t naprawić drugi problem: przeciąganie na kciuku nie powoduje właściwego przewijania listy. Jak wspomniałem powyżej, wydaje się, że właściwą rzeczą byłoby zastąpienie computeVerticalScrollExtent(), ale system nigdy nie wywoła tej metody. Nawet przesłoniłem to, aby po prostu wyrzucić wyjątek, a moja aplikacja nigdy się nie zawiesza.

Mam nadzieję, że to przynajmniej pomoże wskazać ludzi we właściwym kierunku, aby uzyskać pełne rozwiązanie.

PS: Implementacje computeVerticalScrollRange() i computeVerticalScrollOffset() Zawarłem tę odpowiedź są celowo proste (czytaj: fałszywe). "Prawdziwe" implementacje byłyby znacznie bardziej złożone; domyślne implementacje LinearLayoutManager uwzględniają orientację urządzenia, pierwsze i ostatnie widoczne elementy na liście, liczbę elementów poza ekranem w obu kierunkach, płynne przewijanie, różne flagi układu i tak dalej.