7

我正在使用 aLinearSnapHelper将我的RecyclerView“卡”中的项目在屏幕上放置到位(我的卡片占据了屏幕的大部分,所以我希望它们卡到位并在每次滑动/甩动/滚动时填满屏幕)。

我正在为如何让卡片更快地卡入到位而苦苦挣扎。我尝试过创建自定义LinearLayoutManager(并calculateSpeedPerPixelscrollToPositionor中编辑方法smoothScrollToPosition)以及自定义RecyclerView(并编辑 fling 方法)。但没有什么影响卡片“卡入”到位的速度。

我想问题是我真的不明白如何LinearSnapHelper将卡片“滚动”到位。它似乎没有使用LinearLayoutManager'sscrollToPositionsmoothScrollToPosition方法。

    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);
4

5 回答 5

6

正如郭玉龙所说,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);
}

或者您可以实现自己的插值器。

于 2017-08-22T14:16:51.983 回答
3

捕捉滚动的速度受 影响RecyclerView.smoothScrollBy()

这是源代码的片段。

图片

覆盖此函数以增加或减少捕捉滚动的速度。

于 2017-01-17T08:34:34.017 回答
2

我最终通过将 ScrollListener 添加到我的 RecycleView,然后创建自定义 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;
                }
        }
    });
于 2016-11-05T04:40:56.640 回答
0

我使用库https://github.com/rubensousa/GravitySnapHelper实现了这一点

您还可以覆盖 findTargetSnapPosition 以获取类似滚动的寻呼机

tweek scrollMsPerInch 增加/减少速度

    val snapHelper : GravitySnapHelper = GravitySnapHelper(Gravity.CENTER)
    
    // the lower the higher the speed, default is 100f
    snapHelper.scrollMsPerInch = 40f

    snapHelper.attachToRecyclerView(binding?.mRecyclerView)
于 2021-01-29T05:53:31.247 回答
-1

实际上,您可以通过简单地复制/粘贴现有​​代码来修改 LinearSnapHelper 和 SnapHelperClass,您唯一要做的就是根据需要在 SnapHelper 上设置 MILLISECONDS_PER_INCH,然后只需使用您创建的 LinearSnapHelper

于 2019-06-18T20:58:51.900 回答