最近项目需求要实现RecyclerView的分页滑动 先上效果图如下(视频压缩成的gif所以滑动切换效果有点卡顿了 效果为每页三条数据的滑动)

一:创建横向布局管理器
/**
* Created by Sunny on 2019/4/1.
*/
public class HorizontalPageLayoutManager extends RecyclerView.LayoutManager implements PageDecorationLastJudge {
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return null;
}
int totalHeight = 0;
int totalWidth = 0;
int offsetY = 0;
int offsetX = 0;
public HorizontalPageLayoutManager(int rows, int columns) {
this.rows = rows;
this.columns = columns;
this.onePageSize = rows * columns;
}
@Override
public boolean canScrollHorizontally() {
return true;
}
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
detachAndScrapAttachedViews(recycler);
int newX = offsetX + dx;
int result = dx;
if (newX > totalWidth) {
result = totalWidth - offsetX;
} else if (newX < 0) {
result = 0 - offsetX;
}
offsetX += result;
offsetChildrenHorizontal(-result);
recycleAndFillItems(recycler, state);
return result;
}
private SparseArray<Rect> allItemFrames = new SparseArray<>();
private int getUsableWidth() {
return getWidth() - getPaddingLeft() - getPaddingRight();
}
private int getUsableHeight() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
int rows = 0;
int columns = 0;
int pageSize = 0;
int itemWidth = 0;
int itemHeight = 0;
int onePageSize = 0;
int itemWidthUsed;
int itemHeightUsed;
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
if (getItemCount() == 0) {
removeAndRecycleAllViews(recycler);
return;
}
if (state.isPreLayout()) {
return;
}
//获取每个Item的平均宽高
itemWidth = getUsableWidth() / columns;
itemHeight = getUsableHeight() / rows;
//计算宽高已经使用的量,主要用于后期测量
itemWidthUsed = (columns - 1) * itemWidth;
itemHeightUsed = (rows - 1) * itemHeight;
//计算总的页数
// pageSize = state.getItemCount() / onePageSize + (state.getItemCount() % onePageSize == 0 ? 0 : 1);
computePageSize(state);
Log.i("zzz", "itemCount=" + getItemCount() + " state itemCount=" + state.getItemCount() + " pageSize=" + pageSize);
//计算可以横向滚动的最大值
totalWidth = (pageSize - 1) * getWidth();
//分离view
detachAndScrapAttachedViews(recycler);
int count = getItemCount();
for (int p = 0; p < pageSize; p++) {
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
int index = p * onePageSize + r * columns + c;
if (index == count) {
//跳出多重循环
c = columns;
r = rows;
p = pageSize;
break;
}
View view = recycler.getViewForPosition(index);
addView(view);
//测量item
measureChildWithMargins(view, itemWidthUsed, itemHeightUsed);
int width = getDecoratedMeasuredWidth(view);
int height = getDecoratedMeasuredHeight(view);
//记录显示范围
Rect rect = all