Czy istnieje sposób na spowolnienie prędkości przewijania za pomocą adaptera przeglądarki w systemie Android?
Wiesz, patrzyłem na ten kod. Nie mogę zrozumieć, co się mylę.
try{
Field mScroller = mPager.getClass().getDeclaredField("mScroller");
mScroller.setAccessible(true);
Scroller scroll = new Scroller(cxt);
Field scrollDuration = scroll.getClass().getDeclaredField("mDuration");
scrollDuration.setAccessible(true);
scrollDuration.set(scroll, 1000);
mScroller.set(mPager, scroll);
}catch (Exception e){
Toast.makeText(cxt, "something happened", Toast.LENGTH_LONG).show();
}
To niczego nie zmienia, a nie ma wyjątków?
child.setNestedScrollingEnabled(false);
pracował dla mnieOdpowiedzi:
Zacząłem od kodu HighFlyer, który rzeczywiście zmienił pole mScroller (co jest świetnym początkiem), ale nie pomógł wydłużyć czasu trwania przewijania, ponieważ ViewPager jawnie przekazuje czas trwania do mScroller, gdy żąda przewijania.
Rozszerzanie ViewPager nie działało, ponieważ nie można zastąpić ważnej metody (smoothScrollTo).
Skończyło się na naprawieniu tego, rozszerzając Scroller o ten kod:
I używając tego w ten sposób:
Zasadniczo zakodowałem czas trwania do 5 sekund i sprawiłem, że mój ViewPager go używa.
Mam nadzieję że to pomoże.
źródło
scroller.setFixedDuration(5000);
podaje błąd? Mówi się, że „Metoda setFixedDuration (int) jest nieokreślona”Chciałem zrobić sam i osiągnąłem rozwiązanie (jednak wykorzystując refleksję). Jest podobny do przyjętego rozwiązania, ale używa tego samego interpolatora i zmienia tylko czas trwania na podstawie współczynnika. Musisz użyć a
ViewPagerCustomDuration
w swoim XML zamiastViewPager
, a następnie możesz to zrobić:ViewPagerCustomDuration.java
:ScrollerCustomDuration.java
:Mam nadzieję, że to komuś pomoże!
źródło
Znalazłem lepsze rozwiązanie w oparciu o odpowiedź @ df778899 i Android ValueAnimator API . Działa dobrze bez refleksów i jest bardzo elastyczny. Nie ma również potrzeby tworzenia niestandardowego ViewPagera i umieszczania go w pakiecie android.support.v4.view. Oto przykład:
źródło
startFakeDrag
iendFakeDrag
ma na celu zrobić więcej, niż jest dostępne poViewPager
wyjęciu z pudełka. To działa świetnie dla mnie i jest dokładnie tym, czego szukałemanimatePagerTransition(final boolean forward
metodę? W tym jestem zdezorientowany. Czy wywołujesz to w jednej zViewPager.OnPageChangeListener
metod interfejsu? Lub gdzie indziej?Jak widać w źródłach ViewPagera, czas trwania rzutowania kontrolowany przez obiekt mScroller. W dokumentacji możemy przeczytać:
Więc jeśli chcesz kontrolować prędkość, możesz zmienić obiekt mScroller poprzez odbicie.
Powinieneś napisać coś takiego:
źródło
To nie jest idealne rozwiązanie, nie możesz spowolnić prędkości, ponieważ jest to
int
. Ale jak dla mnie jest wystarczająco wolny i nie muszę używać refleksji.Zwróć uwagę na pakiet, w którym znajduje się klasa.
smoothScrollTo
ma widoczność pakietu.źródło
Notice the package where the class is
.package-local
fields
/methods
, jeśli po prostu sprawisz, że Android Studio pomyśli, że używasz tego samego pakietu? Czy jestem jedyną, która coś wąchasealing violation
?Wydaje się, że metody fakeDrag na ViewPager zapewniają alternatywne rozwiązanie.
Na przykład spowoduje to stronicowanie od pozycji 0 do 1:
(
count * count
Jest tam tylko po to, aby przyspieszyć przeciąganie)źródło
używałem
Oto przykład:
źródło
Na podstawie przyjętego rozwiązania stworzyłem klasę kotlin z rozszerzeniem do przeglądania pagera. Cieszyć się! :)
źródło
Oto odpowiedź wykorzystująca zupełnie inne podejście. Ktoś mógłby powiedzieć, że to hacky; jednak nie używa refleksji i twierdziłbym, że zawsze będzie działać.
Wewnątrz znajdujemy następujący kod
ViewPager.smoothScrollTo
:Oblicza czas trwania na podstawie kilku rzeczy. Widzisz coś, co możemy kontrolować?
mAdapter.getPageWidth
. Zaimplementujmy ViewPager.OnPageChangeListener w naszym adapterze . Zamierzamy wykryć przewijanie ViewPager i podać fałszywą wartość szerokości . Jeśli chcę, żeby trwanie byłok*100
, wrócę1.0/(k-1)
pogetPageWidth
. Poniżej znajduje się Kotlin impl tej części adaptera, który zmienia czas trwania na 400:Nie zapomnij dodać adaptera jako OnPageChangedListener.
W moim konkretnym przypadku można bezpiecznie założyć, że użytkownik nie może przesuwać palcem, aby przeciągać między stronami. Jeśli musisz wspierać osiadanie po przeciągnięciu, musisz zrobić trochę więcej w swoich obliczeniach.
Jedną wadą jest to, że zależy to od tej zakodowanej na stałe
100
wartości czasu trwania podstawowego w ViewPager. Jeśli to się zmieni, czas trwania zmieni się dzięki temu podejściu.źródło
Chciałem rozwiązać ten sam problem, co wy wszyscy i to jest moje rozwiązanie tego samego problemu, ale myślę, że w ten sposób rozwiązanie jest bardziej elastyczne, ponieważ możesz zmienić czas trwania, jak chcesz, a także zmienić interpolację wartości według potrzeb aby osiągnąć różne efekty wizualne. Moje rozwiązanie przesuwa się ze strony „1” na stronę „2”, więc tylko w rosnących pozycjach, ale można je łatwo zmienić na malejące, wykonując „animProgress - lastFakeDrag” zamiast „lastFakeDrag - animProgress”. Myślę, że jest to najbardziej elastyczne rozwiązanie do wykonania tego zadania.
źródło