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 RecyclerView
largeur 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!