Aktualizacja Google I / O 2019
ViewPager2 jest tutaj!
Firma Google właśnie ogłosiła podczas wykładu „Co nowego w Androidzie” (znanego również jako „Myśl przewodnia Androida”), że pracuje nad nowym ViewPager opartym na RecyclerView!
Ze slajdów:
Podobnie jak ViewPager, ale lepiej
- Łatwa migracja z ViewPager
- Na podstawie RecyclerView
- Obsługa trybu od prawej do lewej
- Umożliwia stronicowanie w pionie
- Ulepszone powiadomienia o zmianie zbioru danych
Możesz sprawdzić najnowszą wersję tutaj, a informacje o wydaniu tutaj . Istnieje również oficjalna próbka .
Osobista opinia: myślę, że to naprawdę potrzebny dodatek. Ostatnio miałem dużo problemów z PagerSnapHelper
oscylacją w lewo w prawo w nieskończoność - zobacz bilet , który otworzyłem.
Nowa odpowiedź (2016)
Możesz teraz po prostu użyć SnapHelpera .
Jeśli chcesz, aby zachowanie przyciągania wyrównane do środka było podobne do ViewPager, użyj PagerSnapHelper :
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
Istnieje również LinearSnapHelper . Wypróbowałem to i jeśli rzucasz energią, przewija 2 przedmioty z 1 rzutem. Osobiście mi się to nie podobało, ale po prostu zdecyduj sam - wypróbowanie tego zajmuje tylko kilka sekund.
Oryginalna odpowiedź (2016)
Po wielu godzinach próbowania 3 różnych rozwiązań znalezionych tutaj w SO w końcu zbudowałem rozwiązanie, które bardzo dokładnie naśladuje zachowanie występujące w pliku ViewPager
.
Rozwiązanie jest oparte na rozwiązaniu @eDizzle , które, jak sądzę, poprawiłem na tyle, aby powiedzieć, że działa prawie jak plik ViewPager
.
Ważne: RecyclerView
szerokość moich przedmiotów jest dokładnie taka sama jak na ekranie. Nie próbowałem z innymi rozmiarami. Używam go również z poziomym LinearLayoutManager
. Myślę, że będziesz musiał dostosować kod, jeśli chcesz przewijać w pionie.
Tutaj masz kod:
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);
}
}
}
}
Cieszyć się!