Mise à jour Google I / O 2019
ViewPager2 est là!
Google vient d'annoncer lors de la conférence «Quoi de neuf dans Android» (alias «La keynote Android») qu'ils travaillaient sur un nouveau ViewPager basé sur RecyclerView!
À partir des diapositives:
Comme ViewPager, mais mieux
- Migration facile depuis ViewPager
- Basé sur RecyclerView
- Prise en charge du mode de droite à gauche
- Permet la pagination verticale
- Amélioration des notifications de modification des ensembles de données
Vous pouvez consulter la dernière version ici et les notes de version ici . Il existe également un échantillon officiel .
Opinion personnelle: je pense que c'est un ajout vraiment nécessaire. J'ai récemment eu beaucoup de problèmes avec l' PagerSnapHelper oscillation gauche droite indéfiniment - voir le ticket que j'ai ouvert.
Nouvelle réponse (2016)
Vous pouvez maintenant simplement utiliser un SnapHelper .
Si vous voulez un comportement d' accrochage centré similaire à ViewPager, utilisez PagerSnapHelper :
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
Il existe également un LinearSnapHelper . Je l'ai essayé et si vous vous lancez avec de l'énergie, il fait défiler 2 éléments avec 1 jet. Personnellement, je n'ai pas aimé, mais décidez par vous-même - l'essayer ne prend que quelques secondes.
Réponse originale (2016)
Après de nombreuses heures à essayer 3 solutions différentes trouvées ici dans SO, j'ai finalement construit une solution qui imite de très près le comportement trouvé dans un fichier ViewPager.
La solution est basée sur la solution @eDizzle , que je pense avoir suffisamment améliorée pour dire qu'elle fonctionne presque comme un ViewPager.
Important: la RecyclerViewlargeur de mes éléments est exactement la même que celle de l'écran. Je n'ai pas essayé avec d'autres tailles. Aussi je l'utilise avec un horizontal LinearLayoutManager. Je pense que vous devrez adapter le code si vous voulez un défilement vertical.
Ici vous avez le code:
public class SnappyRecyclerView extends RecyclerView {
public SnappyRecyclerView(Context context) {
super(context);
}
public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SnappyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean fling(int velocityX, int velocityY) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);
int leftMargin = (screenWidth - lastView.getWidth()) / 2;
int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
int leftEdge = lastView.getLeft();
int rightEdge = firstView.getRight();
int scrollDistanceLeft = leftEdge - leftMargin;
int scrollDistanceRight = rightMargin - rightEdge;
if (Math.abs(velocityX) < 1000) {
if (leftEdge > screenWidth / 2) {
smoothScrollBy(-scrollDistanceRight, 0);
} else if (rightEdge < screenWidth / 2) {
smoothScrollBy(scrollDistanceLeft, 0);
} else {
if (velocityX > 0) {
smoothScrollBy(-scrollDistanceRight, 0);
} else {
smoothScrollBy(scrollDistanceLeft, 0);
}
}
return true;
} else {
if (velocityX > 0) {
smoothScrollBy(scrollDistanceLeft, 0);
} else {
smoothScrollBy(-scrollDistanceRight, 0);
}
return true;
}
}
@Override
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
if (state == SCROLL_STATE_IDLE) {
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) getLayoutManager();
int screenWidth = Resources.getSystem().getDisplayMetrics().widthPixels;
int lastVisibleItemPosition = linearLayoutManager.findLastVisibleItemPosition();
View lastView = linearLayoutManager.findViewByPosition(lastVisibleItemPosition);
int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
View firstView = linearLayoutManager.findViewByPosition(firstVisibleItemPosition);
int leftMargin = (screenWidth - lastView.getWidth()) / 2;
int rightMargin = (screenWidth - firstView.getWidth()) / 2 + firstView.getWidth();
int leftEdge = lastView.getLeft();
int rightEdge = firstView.getRight();
int scrollDistanceLeft = leftEdge - leftMargin;
int scrollDistanceRight = rightMargin - rightEdge;
if (leftEdge > screenWidth / 2) {
smoothScrollBy(-scrollDistanceRight, 0);
} else if (rightEdge < screenWidth / 2) {
smoothScrollBy(scrollDistanceLeft, 0);
}
}
}
}
Prendre plaisir!