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