Existe-t-il un moyen de ralentir la vitesse de défilement avec l'adaptateur viewpager dans Android?
Vous savez, j'ai regardé ce code. Je ne peux pas comprendre ce que je me trompe.
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();
}
Cela ne change rien mais aucune exception ne se produit?
child.setNestedScrollingEnabled(false);
travaillé pour moiRéponses:
J'ai commencé avec le code de HighFlyer qui a en effet changé le champ mScroller (ce qui est un bon début) mais n'a pas aidé à prolonger la durée du défilement car ViewPager transmet explicitement la durée au mScroller lors de la demande de défilement.
L'extension de ViewPager ne fonctionnait pas car la méthode importante (smoothScrollTo) ne peut pas être remplacée.
J'ai fini par résoudre ce problème en étendant Scroller avec ce code:
Et en l'utilisant comme ceci:
J'ai fondamentalement codé la durée à 5 secondes et j'ai fait en sorte que mon ViewPager l'utilise.
J'espère que cela t'aides.
la source
scroller.setFixedDuration(5000);
donne une erreur? Il dit "La méthode setFixedDuration (int) est indéfinie"J'ai voulu faire moi-même et j'ai trouvé une solution (en utilisant la réflexion, cependant). Elle est similaire à la solution acceptée mais utilise le même interpolateur et ne modifie la durée qu'en fonction d'un facteur. Vous devez utiliser a
ViewPagerCustomDuration
dans votre XML au lieu deViewPager
, puis vous pouvez le faire:ViewPagerCustomDuration.java
:ScrollerCustomDuration.java
:J'espère que cela aide quelqu'un!
la source
J'ai trouvé une meilleure solution, basée sur la réponse de @ df778899 et l' API Android ValueAnimator . Cela fonctionne bien sans réflexion et est très flexible. De plus, il n'est pas nécessaire de créer un ViewPager personnalisé et de le placer dans le package android.support.v4.view. Voici un exemple:
la source
startFakeDrag
etendFakeDrag
est censé être pour faire plus que ce qui est disponible dansViewPager
la boîte. Cela fonctionne très bien pour moi et c'est exactement ce que je recherchaisanimatePagerTransition(final boolean forward
méthode? C'est ce dont je suis confus. L'appelez-vous dans l'une desViewPager.OnPageChangeListener
méthodes d'interface? Ou ailleurs?Comme vous pouvez le voir dans les sources de ViewPager, la durée du fling est contrôlée par l'objet mScroller. Dans la documentation, nous pouvons lire:
Ainsi, si vous souhaitez contrôler la vitesse, vous pouvez modifier l'objet mScroller par réflexion.
Vous devriez écrire quelque chose comme ceci:
la source
Ce n'est pas la solution parfaite, vous ne pouvez pas ralentir la vitesse car c'est un
int
. Mais pour moi, c'est assez lent et je n'ai pas besoin d'utiliser la réflexion.Notez le package où se trouve la classe.
smoothScrollTo
a une visibilité sur les packages.la source
Notice the package where the class is
.package-local
fields
/methods
, si vous faites simplement croire à Android Studio que vous utilisez le même package? Suis-je le seul à en sentirsealing violation
?Les méthodes fakeDrag sur ViewPager semblent fournir une solution alternative.
Par exemple, cela va page de l'élément 0 à 1:
(Le
count * count
est juste là pour accélérer la vitesse de traînée au fur et à mesure)la source
j'ai utilisé
Voici l'exemple:
la source
Sur la base de la solution acceptée, j'ai créé une classe kotlin avec une extension pour afficher le pager. Prendre plaisir! :)
la source
Voici une réponse utilisant une approche totalement différente. Quelqu'un pourrait dire que cela a une impression de piratage; cependant, il n'utilise pas la réflexion, et je dirais que cela fonctionnera toujours.
On retrouve le code suivant à l'intérieur
ViewPager.smoothScrollTo
:Il calcule la durée en fonction de plusieurs éléments. Vous voyez tout ce que nous pouvons contrôler?
mAdapter.getPageWidth
. Implémentons ViewPager.OnPageChangeListener dans notre adaptateur . Nous allons détecter quand le ViewPager défile et donner une fausse valeur pour la largeur . Si je veux que la durée soitk*100
, alors je reviendrai1.0/(k-1)
pourgetPageWidth
. Ce qui suit est Kotlin impl de cette partie de l'adaptateur qui transforme la durée en 400:N'oubliez pas d'ajouter l'adaptateur en tant que OnPageChangedListener.
Mon cas particulier peut supposer en toute sécurité que l'utilisateur ne peut pas glisser pour faire glisser entre les pages. Si vous devez prendre en charge la stabilisation après un glissement, vous devez en faire un peu plus dans votre calcul.
Un inconvénient est que cela dépend de cette
100
valeur de durée de base codée en dur dans ViewPager. Si cela change, vos durées changent avec cette approche.la source
Je voulais résoudre le même problème que vous tous et c'est ma solution pour le même problème, mais je pense que de cette façon, la solution est plus flexible car vous pouvez modifier la durée comme vous le souhaitez et également modifier l'interpolation des valeurs comme vous le souhaitez pour obtenir différents effets visuels. Ma solution glisse de la page "1" à la page "2", donc uniquement dans des positions croissantes, mais peut facilement être modifiée pour aller dans des positions décroissantes en faisant "animProgress - lastFakeDrag" au lieu de "lastFakeDrag - animProgress". Je pense que c'est la solution la plus flexible pour effectuer cette tâche.
la source