Aggiornamento di Google I / O 2019
ViewPager2 è qui!
Google ha appena annunciato al discorso "Novità di Android" (ovvero "Il keynote di Android") che stanno lavorando a un nuovo ViewPager basato su RecyclerView!
Dalle diapositive:
Come ViewPager, ma migliore
- Facile migrazione da ViewPager
- Basato su RecyclerView
- Supporto della modalità da destra a sinistra
- Consente il paging verticale
- Notifiche di modifica del set di dati migliorate
Puoi controllare l'ultima versione qui e le note di rilascio qui . C'è anche un campione ufficiale .
Opinione personale: penso che questa sia un'aggiunta davvero necessaria. Recentemente ho avuto molti problemi con l' PagerSnapHelper oscillazione sinistra destra indefinitamente - vedi il biglietto che ho aperto.
Nuova risposta (2016)
Ora puoi semplicemente usare uno SnapHelper .
Se desideri un comportamento di snap allineato al centro simile a ViewPager, usa PagerSnapHelper :
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
C'è anche un LinearSnapHelper . L'ho provato e se lanci con energia, scorre 2 elementi con 1 avventura. Personalmente non mi è piaciuto, ma decidi da solo: provarlo richiede solo pochi secondi.
Risposta originale (2016)
Dopo molte ore di tentativi di 3 diverse soluzioni trovate qui in SO, ho finalmente creato una soluzione che imita molto da vicino il comportamento trovato in un file ViewPager.
La soluzione si basa sulla soluzione @eDizzle , che credo di aver migliorato abbastanza da dire che funziona quasi come un file ViewPager.
Importante: la RecyclerViewlarghezza dei miei articoli è esattamente la stessa dello schermo. Non ho provato con altre dimensioni. Anche io lo uso con un orizzontale LinearLayoutManager. Penso che dovrai adattare il codice se vuoi lo scorrimento verticale.
Ecco il codice:
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);
}
}
}
}
Godere!