简洁:
RecyclerView在24.2.0版本中新增了SnapHelper这个辅助类,用于辅助RecyclerView在滚动结束时将Item对齐到某个位置。特别是列表横向滑动时,很多时候不会让列表滑到任意位置,而是会有一定的规则限制,这时候就可以通过SnapHelper来定义对齐规则了。
SnapHelper是一个抽象类,官方提供了一个LinearSnapHelper的子类,可以让RecyclerView滚动停止时相应的Item停留中间位置。25.1.0版本中官方又提供了一个PagerSnapHelper的子类,可以使RecyclerView像ViewPager一样的效果,一次只能滑一页,而且居中显示。
这两个子类使用方式也很简单,只需要创建对象之后调用attachToRecyclerView()
附着到对应的RecyclerView对象上就可以了。
new LinearSnapHelper().attachToRecyclerView(mRecyclerView);
//或者
new PagerSnapHelper().attachToRecyclerView(mRecyclerView);
一、先看效果
我现在项目上最终实现的效果就是这样的。横向滚动,每次滚动之后,都保证左边是贴合可见的
二、自定义滚动辅助类
/**
* @Author : 马占柱
* Time : 2024/1/18 11:19
* Desc : 自定义滚动辅助类,每次滚动之后,展示完整的item
*/
public class GallerySnapHelper extends SnapHelper {
public static final String TAG = "GallerySnapHelper";
private static final float INVALID_DISTANCE = 1f;
//SnapHelper中该值为100,这里改为40
private static final float MILLISECONDS_PER_INCH = 40f;
private OrientationHelper mHorizontalHelper;
private RecyclerView mRecyclerView;
@Override
public void attachToRecyclerView(@Nullable RecyclerView recyclerView) throws IllegalStateException {
mRecyclerView = recyclerView;
super.attachToRecyclerView(recyclerView);
}
@Override
public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager, @NonNull View targetView) {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
out[0] = distanceToStart(targetView, getHorizontalHelper(layoutManager));
} else {
out[0] = 0;
}
return out;
}
//targetView的start坐标与RecyclerView的paddingStart之间的差值
//就是需要滚动调整的距离
private int distanceToStart(View targetView, OrientationHelper helper) {
LogUtils.ld(TAG, "distanceToStart dx1=" + helper.getDecoratedStart(targetView) + ", dx2=" + helper.getStartAfterPadding());
return helper.getDecoratedStart(targetView) - helper.getStartAfterPadding();
}
@Nullable
protected LinearSmoothScroller createSnapScroller(final RecyclerView.LayoutManager layout