我使用LinearSnapHelper在我的RecyclerView" snap"屏幕上的位置(我的卡占据了屏幕的大部分,因此我希望它们能够卡入到位并在每次滑动/滚动/滚动时填充屏幕。)
我正在努力解决如何让卡片快速移动更快。我尝试过创建自定义LinearLayoutManager(并在scrollToPosition或smoothScrollToPosition中编辑calculateSpeedPerPixel方法),以及自定义RecyclerView(并编辑fling方法)。但没有什么能影响卡片的速度和快速消费。到位。
我想问题是我并不真正理解LinearSnapHelper"如何滚动"卡到位。它似乎没有使用LinearLayoutManager的scrollToPosition或smoothScrollToPosition方法。
有任何帮助吗?非常感谢!
snapHelper = new LinearSnapHelper() {
@Override
public int findTargetSnapPosition(RecyclerView.LayoutManager layoutManager, int velocityX, int velocityY) {
View centerView = findSnapView(layoutManager);
if (centerView == null) {
return RecyclerView.NO_POSITION;
}
int position = layoutManager.getPosition(centerView);
int targetPosition = -1;
if (layoutManager.canScrollHorizontally()) {
if (velocityX < 0) {
targetPosition = position - 1;
} else {
targetPosition = position + 1;
}
}
if (layoutManager.canScrollVertically()) {
if (velocityY > 0) {
targetPosition = position + 1;
} else {
targetPosition = position - 1;
}
}
final int firstItem = 0;
final int lastItem = layoutManager.getItemCount() - 1;
targetPosition = Math.min(lastItem, Math.max(targetPosition, firstItem));
return targetPosition;
}
};
snapHelper.attachToRecyclerView(mRecyclerView);
答案 0 :(得分:5)
正如郭玉龙所说,SnapHelper调用RecyclerView.smoothScrollBy()方法。它使用默认的sQuinticInterpolator。 要更改快照的速度,您可以执行下一步:
public class SlowdownRecyclerView extends RecyclerView {
// Change pow to control speed.
// Bigger = faster. RecyclerView default is 5.
private static final int POW = 2;
private Interpolator interpolator;
public SlowdownRecyclerView(Context context) {
super(context);
createInterpolator();
}
public SlowdownRecyclerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
createInterpolator();
}
public SlowdownRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
createInterpolator();
}
private void createInterpolator(){
interpolator = new Interpolator() {
@Override
public float getInterpolation(float t) {
t = Math.abs(t - 1.0f);
return (float) (1.0f - Math.pow(t, POW));
}
};
}
@Override
public void smoothScrollBy(int dx, int dy) {
super.smoothScrollBy(dx, dy, interpolator);
}
或者您可以实现自己的插补器。
答案 1 :(得分:3)
捕捉滚动的速度受RecyclerView.smoothScrollBy()
的影响。
以下是源代码片段。
覆盖此功能以增加或减少捕捉滚动的速度。
答案 2 :(得分:2)
我最后通过向我的RecycleView添加ScrollListener,然后创建自定义LinearLayoutManager和自定义smoothScrollToPosition方法来完成此操作。
final CustomLinearLayoutManager mLayoutManager = new CustomLinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
private boolean scrollingUp;
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
scrollingUp = dy < 0;
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
int visiblePosition = scrollingUp ? mLayoutManager.findFirstVisibleItemPosition() : mLayoutManager.findLastVisibleItemPosition();
int completelyVisiblePosition = scrollingUp ? mLayoutManager
.findFirstCompletelyVisibleItemPosition() : mLayoutManager
.findLastCompletelyVisibleItemPosition();
if (visiblePosition != completelyVisiblePosition) {
recyclerView.smoothScrollToPosition(visiblePosition);
return;
}
}
});
答案 3 :(得分:0)
实际上,您可以通过简单地复制/粘贴现有代码来修改LinearSnapHelper和SnapHelperClass,唯一要做的就是根据需要在SnapHelper上设置MILLISECONDS_PER_INCH,然后仅使用创建的LinearSnapHelper
答案 4 :(得分:0)
我使用库 https://github.com/rubensousa/GravitySnapHelper
实现了这一点你也可以覆盖 findTargetSnapPosition 来获得类似滚动的寻呼机
调整 scrollMsPerInch 以增加/减少速度
val snapHelper : GravitySnapHelper = GravitySnapHelper(Gravity.CENTER)
// the lower the higher the speed, default is 100f
snapHelper.scrollMsPerInch = 40f
snapHelper.attachToRecyclerView(binding?.mRecyclerView)