Cập nhật Google I / O 2019
ViewPager2 là ở đây!
Google vừa thông báo tại buổi nói chuyện 'Có gì mới trong Android' (hay còn gọi là 'Bài phát biểu của Android') rằng họ đang làm việc trên một ViewPager mới dựa trên RecyclerView!
Từ các trang trình bày:
Giống như ViewPager, nhưng tốt hơn
- Di chuyển dễ dàng từ ViewPager
- Dựa trên RecyclerView
- Hỗ trợ chế độ từ phải sang trái
- Cho phép phân trang dọc
- Thông báo thay đổi tập dữ liệu được cải thiện
Bạn có thể kiểm tra phiên bản mới nhất tại đây và ghi chú phát hành tại đây . Cũng có một mẫu chính thức .
Ý kiến cá nhân: Tôi nghĩ đây là một sự bổ sung thực sự cần thiết. Gần đây tôi đã gặp rất nhiều rắc rối với việc PagerSnapHelper
dao động trái phải vô thời hạn - hãy xem vé tôi đã mở.
Câu trả lời mới (2016)
Bây giờ bạn có thể chỉ cần sử dụng SnapHelper .
Nếu bạn muốn hành vi chụp nhanh căn giữa tương tự như ViewPager thì hãy sử dụng PagerSnapHelper :
SnapHelper snapHelper = new PagerSnapHelper();
snapHelper.attachToRecyclerView(recyclerView);
Ngoài ra còn có một LinearSnapHelper . Tôi đã thử nó và nếu bạn ném bằng năng lượng thì nó sẽ cuộn 2 mục với 1 lần ném. Cá nhân tôi không thích nó, nhưng hãy tự quyết định - thử chỉ mất vài giây.
Câu trả lời gốc (2016)
Sau nhiều giờ thử 3 giải pháp khác nhau được tìm thấy ở đây trong SO, cuối cùng, tôi đã tạo ra một giải pháp bắt chước rất gần với hành vi được tìm thấy trong a ViewPager
.
Giải pháp dựa trên giải pháp @eDizzle , mà tôi tin rằng tôi đã cải thiện đủ để nói rằng nó hoạt động gần giống như một ViewPager
.
Quan trọng: RecyclerView
chiều rộng các mặt hàng của tôi giống hệt như màn hình. Tôi chưa thử với các kích thước khác. Ngoài ra tôi sử dụng nó với một chiều ngang LinearLayoutManager
. Tôi nghĩ rằng bạn sẽ cần phải điều chỉnh mã nếu bạn muốn cuộn dọc.
Ở đây bạn có mã:
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);
}
}
}
}
Thưởng thức!