Atualização do Google I / O 2019
ViewPager2 está aqui!
O Google acaba de anunciar na palestra 'Novidades no Android' (também conhecido como 'The Android keynote') que estão trabalhando em um novo ViewPager baseado no RecyclerView!
Dos slides:
Como o ViewPager, mas melhor
- Migração fácil do ViewPager
- Baseado em RecyclerView
- Suporte para modo da direita para a esquerda
- Permite paginação vertical
- Notificações de mudança de conjunto de dados aprimoradas
Você pode verificar a versão mais recente aqui e as notas de lançamento aqui . Também existe uma amostra oficial .
Opinião pessoal: Acho que é uma adição muito necessária. Recentemente, tive muitos problemas com a PagerSnapHelper
oscilação da esquerda para a direita indefinidamente - veja o tíquete que abri.
Nova resposta (2016)
Agora você pode apenas usar um SnapHelper .
Se você deseja um comportamento de alinhamento centralizado semelhante ao ViewPager , use PagerSnapHelper :
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
Também existe um LinearSnapHelper . Eu tentei e se você arremessar com energia, ele rola 2 itens com 1 arremesso. Pessoalmente, não gostei, mas decida por si mesmo - tentar leva apenas alguns segundos.
Resposta original (2016)
Depois de muitas horas tentando três soluções diferentes encontradas aqui no SO, finalmente construí uma solução que imita muito de perto o comportamento encontrado em a ViewPager
.
A solução é baseada na solução @eDizzle , que acredito ter melhorado o suficiente para dizer que funciona quase como um ViewPager
.
Importante: a RecyclerView
largura dos meus itens é exatamente igual à da tela. Não tentei com outros tamanhos. Também uso com uma horizontal LinearLayoutManager
. Acho que você precisará adaptar o código se quiser rolagem vertical.
Aqui você tem o código:
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);
}
}
}
}
Apreciar!