J'ai cherché longtemps pour faire fonctionner un ViewPager à l'intérieur d'un autre ViewPager et j'ai trouvé la solution par "Android Noob" ici. Merci beaucoup pour cela!
Je voulais aussi partager ma solution. J'ai ajouté la possibilité de passer la gestion du balayage au ViewPager environnant une fois que le dernier élément (le plus à droite) dans le ViewPager interne est atteint. Pour éviter les erreurs graphiques, je sauvegarde également la première direction de balayage pour le dernier élément: c'est-à-dire que si vous faites d'abord un balayage vers la gauche, un balayage minimal vers la droite ne réinitialise pas l'état du défilement.
public class GalleryViewPager extends ViewPager {
/** la dernière position x */
private float lastX;
/** si le premier balayage était de gauche à droite (->), ne pas écouter les balayages de droite */
private boolean slidingLeft;
/** si le premier balayage était de droite à gauche (<-), ne pas écouter les balayages de gauche */
private boolean slidingRight;
public GalleryViewPager(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public GalleryViewPager(final Context context) {
super(context);
}
@Override
public boolean onTouchEvent(final MotionEvent ev) {
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
// Interdire au parent ViewPager d'intercepter les événements tactiles.
this.getParent().requestDisallowInterceptTouchEvent(true);
// sauvegarder la position x actuelle
this.lastX = ev.getX();
break;
case MotionEvent.ACTION_UP:
// Autoriser au parent ViewPager d'intercepter les événements tactiles.
this.getParent().requestDisallowInterceptTouchEvent(false);
// sauvegarder la position x actuelle
this.lastX = ev.getX();
// réinitialiser les actions de balayage
this.slidingLeft = false;
this.slidingRight = false;
break;
case MotionEvent.ACTION_MOVE:
/*
* si c'est le premier élément, un défilement de gauche à
* droite devrait naviguer dans le ViewPager environnant
*/
if (this.getCurrentItem() == 0) {
// un balayage de gauche à droite (->)?
if (this.lastX <= ev.getX() && !this.slidingRight) {
// activer l'interception tactile du parent -> le parent peut faire un balayage
this.getParent().requestDisallowInterceptTouchEvent(false);
} else {
/*
* si le premier balayage était de droite à gauche, ne pas écouter les balayages
* de gauche à droite. cela corrige les erreurs graphiques où l'utilisateur fait d'abord un balayage
* à droite, puis à gauche et l'état du défilement est réinitialisé
*/
this.slidingRight = true;
// sauvegarder la position x actuelle
this.lastX = ev.getX();
this.getParent().requestDisallowInterceptTouchEvent(true);
}
} else
/*
* si c'est le dernier élément, un défilement de droite à
* gauche devrait naviguer dans le ViewPager environnant
*/
if (this.getCurrentItem() == this.getAdapter().getCount() - 1) {
// un balayage de droite à gauche (<-)?
if (this.lastX >= ev.getX() && !this.slidingLeft) {
// activer l'interception tactile du parent -> le parent peut faire un balayage
this.getParent().requestDisallowInterceptTouchEvent(false);
} else {
/*
* si le premier balayage était de gauche à droite, ne pas écouter les balayages
* de droite à gauche. cela corrige les erreurs graphiques où l'utilisateur fait d'abord un balayage
* à gauche, puis à droite et l'état du défilement est réinitialisé
*/
this.slidingLeft = true;
// sauvegarder la position x actuelle
this.lastX = ev.getX();
this.getParent().requestDisallowInterceptTouchEvent(true);
}
}
break;
}
super.onTouchEvent(ev);
return true;
}
}
J'espère que cela aidera quelqu'un à l'avenir!
4 votes
Cela est peu probable de fonctionner, pour la même raison pour laquelle vous ne pouvez généralement pas avoir des éléments défilables à l'intérieur d'autres éléments défilables -- ils ont tendance à se disputer les événements tactiles.
2 votes
Oui... c'est pourquoi je demande :).
0 votes
Est-ce que ma réponse vous a aidé en quoi que ce soit ?
0 votes
Il y a tellement de choses que vous pouvez forcer le framework à faire, mais elles sont appelées Anti-patterns et doivent être évitées. Elles ne sont pas durables à long terme. Veuillez repenser votre approche :)
0 votes
Vérifiez ma réponse stackoverflow.com/a/25800572/2868352