J'ai implémenté SwipeRefreshLayout
et ViewPager
dans mon application mais il y a un gros problème: chaque fois que je vais balayer vers la gauche / droite pour basculer entre les pages, le défilement est trop sensible. Un petit glissement vers le bas déclenchera également l' SwipeRefreshLayout
actualisation.
Je souhaite définir une limite au début du balayage horizontal, puis forcer l'horizontale uniquement jusqu'à ce que le balayage soit terminé. En d'autres termes, je souhaite annuler le balayage vertical lorsque le doigt se déplace horizontalement.
Ce problème ne se produit que ViewPager
si je glisse vers le bas et que la SwipeRefreshLayout
fonction d'actualisation est déclenchée (la barre est affichée) et que je déplace mon doigt horizontalement, cela ne permet toujours que les balayages verticaux.
J'ai essayé d'étendre la ViewPager
classe mais cela ne fonctionne pas du tout:
public class CustomViewPager extends ViewPager {
public CustomViewPager(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean in = super.onInterceptTouchEvent(ev);
if (in) {
getParent().requestDisallowInterceptTouchEvent(true);
this.requestDisallowInterceptTouchEvent(true);
}
return false;
}
}
Mise en page xml:
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/viewTopic"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.myapp.listloader.foundation.CustomViewPager
android:id="@+id/topicViewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.SwipeRefreshLayout>
toute aide serait appréciée Merci
la source
SwipeRefreshLayout
?Réponses:
Je ne sais pas si vous rencontrez toujours ce problème, mais l'application i / O Google I / O résout ce problème ainsi:
J'ai utilisé le même et fonctionne assez bien.
EDIT: Utilisez addOnPageChangeListener () au lieu de setOnPageChangeListener ().
la source
Résolu très simplement sans rien étendre
travaille comme un charme
la source
View
que vous pourriez avoir à l'intérieur duViewPager
, car ilSwipeRefreshLayout
permet même le défilement vertical uniquement pour son enfant de niveau supérieur (et dans les API inférieures à ICS uniquement s'il se trouve que c'est unListView
) .ViewPager
intérieurSwipeRefrestLayout
et le ViewPager aListview
!SwipeRefreshLayout
laissez-moi faire défiler vers le bas, mais en faisant défiler vers le haut, cela déclenche la progression de l'actualisation. Toute suggestion?J'ai rencontré votre problème. Personnaliser le SwipeRefreshLayout résoudrait le problème.
Voir la ref: lien
la source
Je me suis basé sur une réponse précédente, mais j'ai trouvé que cela fonctionnait un peu mieux. Le mouvement commence par un événement ACTION_MOVE et se termine par ACTION_UP ou ACTION_CANCEL d'après mon expérience.
la source
Pour une raison connue d'eux seuls, l'équipe de développement de la bibliothèque de support a jugé bon d' intercepter de force tous les événements de mouvement de traînée verticale de
SwipeRefreshLayout
la disposition enfant de, même lorsqu'un enfant demande spécifiquement la propriété de l'événement. La seule chose qu'ils vérifient est que l'état de défilement vertical de son enfant principal est à zéro (dans le cas où son enfant est défilable verticalement). LarequestDisallowInterceptTouchEvent()
méthode a été remplacée par un corps vide et le (pas si) commentaire éclairant "Nope".Le moyen le plus simple de résoudre ce problème serait de simplement copier la classe de la bibliothèque de support dans votre projet et de supprimer le remplacement de méthode.
ViewGroup
L'implémentation de utilise l'état interne pour la gestiononInterceptTouchEvent()
, vous ne pouvez donc pas simplement remplacer à nouveau la méthode et la dupliquer. Si vous voulez vraiment remplacer l'implémentation de la bibliothèque de support, vous devrez configurer un indicateur personnalisé lors des appels àrequestDisallowInterceptTouchEvent()
, et remplaceronInterceptTouchEvent()
etonTouchEvent()
(ou éventuellement piratercanChildScrollUp()
) le comportement en fonction de cela.la source
J'ai trouvé une solution pour ViewPager2. J'utilise la réflexion pour réduire la sensibilité de la traînée comme ceci:
Cela fonctionne comme un charme pour moi.
la source
Il y a un problème avec la solution de nhasan:
Si le balayage horizontal qui déclenche l'
setEnabled(false)
appel sur leSwipeRefreshLayout
dans leOnPageChangeListener
se produit alors que leSwipeRefreshLayout
a déjà reconnu un Pull-to-Reload mais n'a pas encore appelé le rappel de notification, l'animation disparaît mais l'état interne duSwipeRefreshLayout
reste sur "rafraîchissant" pour toujours car non des rappels de notification sont appelés qui pourraient réinitialiser l'état. Du point de vue de l'utilisateur, cela signifie que Pull-to-Reload ne fonctionne plus car tous les mouvements de traction ne sont pas reconnus.Le problème ici est que l'
disable(false)
appel supprime l'animation du spinner et que le rappel de notification est appelé à partir de laonAnimationEnd
méthode d'un AnimationListener interne pour ce spinner qui est mis dans le désordre de cette façon.Il a certes fallu notre testeur avec les doigts les plus rapides pour provoquer cette situation, mais cela peut également arriver de temps en temps dans des scénarios réalistes.
Une solution pour résoudre ce problème consiste à remplacer la
onInterceptTouchEvent
méthodeSwipeRefreshLayout
comme suit:Utilisez
MySwipeRefreshLayout
dans votre mise en page - Fichier et modifiez le code de la solution de mhasan enla source
Il peut y avoir un problème avec la réponse @huu duy lorsque le ViewPager est placé dans un conteneur à défilement vertical qui, à son tour, est placé dans le SwiprRefreshLayout Si le conteneur à défilement du contenu n'est pas entièrement défilé vers le haut, il peut être impossible de activez le balayage pour actualiser dans le même geste de défilement vers le haut. En effet, lorsque vous commencez à faire défiler le conteneur intérieur et à déplacer le doigt horizontalement plus que mTouchSlop involontairement (qui est de 8dp par défaut), le CustomSwipeToRefresh proposé refuse ce geste. Un utilisateur doit donc essayer une fois de plus pour commencer à actualiser. Cela peut paraître étrange pour l'utilisateur. J'ai extrait le code source du SwipeRefreshLayout original de la bibliothèque de support vers mon projet et réécrit le onInterceptTouchEvent ().
Voir mon exemple de projet sur Github .
la source