这个东西花哨的特别难,简单的特别简单,Github有一堆,
今天具体了解一下,方便以后有需求 ,找到相近的效果,知道在哪里修改一些参数就可以了
首先是自定义一个extends LayoutManager
public class CustomLayoutManager extends RecyclerView.LayoutManager {
// 设置布局宽高的 这里让它宽高 包裹内容
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
, RecyclerView.LayoutParams.WRAP_CONTENT);
}
// 这个方法是把具体的View 添加到RecyclerView
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
// 定义竖直方向的偏移量
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View childview = recycler.getViewForPosition(i);
// 添加进去
addView(childview);
// 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
measureChildWithMargins(childview, 0, 0);
// 一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
int width = getDecoratedMeasuredWidth(childview);
int height = getDecoratedMeasuredHeight(childview);
// 对应onLayout 方法
layoutDecorated(childview, 0, offsetY, width, height + offsetY);
offsetY += height;
}
}
}
这里对应的是 Y轴的操作 所以是竖直方向的
效果
修改一下其中的Y轴操作 ,让他横着展示
// 这个方法是把具体的View 添加到RecyclerView
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
// 定义竖直方向的偏移量
int offsetX = 0;
for (int i = 0; i < getItemCount(); i++) {
View childview = recycler.getViewForPosition(i);
// 添加进去
addView(childview);
// 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
measureChildWithMargins(childview, 0, 0);
// 一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
int width = getDecoratedMeasuredWidth(childview);
int height = getDecoratedMeasuredHeight(childview);
// 对应onLayout 方法
layoutDecorated(childview, offsetX, 0, width+offsetX, height );
offsetX += width;
}
}
效果
然后是:加上滑动
@Override
public boolean canScrollHorizontally() {
return true;
}
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
offsetChildrenHorizontal(-dx);
return dx;
}
这样的写下来是无线滑 可能需要判断是够到头了
判断到头
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dx;
// 如果滑动到最顶部
if (mSumDx + dx < 0) {
travel = -mSumDx;
}
mSumDx += travel;
//平移容器内的View
offsetChildrenHorizontal(-travel);
return dx;
}
判断到底
我们需要先获取所有的 宽度
public class CustomLayoutManager extends RecyclerView.LayoutManager {
// 设置布局宽高的 这里让它宽高 包裹内容
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
, RecyclerView.LayoutParams.WRAP_CONTENT);
}
// 这个方法是把具体的View 添加到RecyclerView
private int mTotalWidth;
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
// 定义竖直方向的偏移量
int offsetX = 0;
for (int i = 0; i < getItemCount(); i++) {
View childview = recycler.getViewForPosition(i);
// 添加进去
addView(childview);
// 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
measureChildWithMargins(childview, 0, 0);
// 一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
int width = getDecoratedMeasuredWidth(childview);
int height = getDecoratedMeasuredHeight(childview);
// 对应onLayout 方法
layoutDecorated(childview, offsetX, 0, width + offsetX, height);
offsetX += width;
}
// 取一个最大的
mTotalWidth = Math.max(offsetX, getHorizontalSpace());
}
/**
* 总的高度 减去 左padding 右padding
*
* @return
*/
private int getHorizontalSpace() {
return getWidth() - getPaddingLeft() - getPaddingRight();
}
@Override
public boolean canScrollHorizontally() {
return true;
}
// 一个中间量
private int mSumDx = 0;
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dx;
// 如果滑动到最顶部
if (mSumDx + dx < 0) {
travel = -mSumDx;
} else if (mSumDx + dx > mTotalWidth - getHorizontalSpace()) {
travel = mTotalWidth - getHorizontalSpace() - mSumDx;
}
mSumDx += travel;
//平移容器内的View
offsetChildrenHorizontal(-travel);
return dx;
}
}
效果:
横的最完了 竖着改一改
public class CustomLayoutManager extends RecyclerView.LayoutManager {
// 设置布局宽高的 这里让它宽高 包裹内容
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT
, RecyclerView.LayoutParams.WRAP_CONTENT);
}
// 这个方法是把具体的View 添加到RecyclerView
private int mTotalHeight;
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
// 定义竖直方向的偏移量
int offsetY = 0;
for (int i = 0; i < getItemCount(); i++) {
View childview = recycler.getViewForPosition(i);
// 添加进去
addView(childview);
// 测量子视图使用标准的测量策略,将母公司的填充回收商看来,任何添加物品装饰和孩子考虑利润
measureChildWithMargins(childview, 0, 0);
// 一种 属于RecyclerView 的 测量方式 就像 自定义View的 onMeasure
int width = getDecoratedMeasuredWidth(childview);
int height = getDecoratedMeasuredHeight(childview);
// 对应onLayout 方法
layoutDecorated(childview, 0, offsetY, width , height + offsetY);
offsetY += height;
}
// 取一个最大的
mTotalHeight = Math.max(offsetY, getVerticalSpace());
}
/**
* 总的高度 减去 上padding 下padding
*
* @return
*/
private int getVerticalSpace() {
return getHeight() - getPaddingTop() - getPaddingBottom();
}
// 一个中间量
private int mSumDy = 0;
@Override
public boolean canScrollVertically() {
return true;
}
@Override
public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
int travel = dy;
// 如果滑动到最顶部
if (mSumDy + dy < 0) {
travel = -mSumDy;
} else if (mSumDy + dy > mTotalHeight - getVerticalSpace()) {
travel = mTotalHeight - getVerticalSpace() - mSumDy;
}
mSumDy += travel;
//平移容器内的View
offsetChildrenVertical(-travel);
return dy;
}
}
可以以这个为基础进行扩展 先参考一下别人的
比如:
这个效果