Android : 控制在回收站视图上的平滑滚动

Android : Control Smooth scroll over recycler view

我正在将 Recyclerview 与 CardView 一起使用。我知道如何控制列表视图的速度。但不适用于 Recyclerview。

我搜索了很多,找到了 class 名字 SmoothScroll。如何使用它?我不知道!现在 Recyclerview 默认滚动速度很快。

更新:

我用

总结了 Gil Answer

当你说“smoothScroll”时,你的意思不清楚。您可能指的是自动滚动到指定位置的自动“smoothScrollToPosition”,您可能指的是手动滚动,也可能指的是快速移动。为了繁荣,我现在将尝试回答所有这些问题。

1.自动平滑滚动。

在布局管理器中,您需要实现 smoothScrollToPosition 方法:

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, State state, int position)
    {
        // A good idea would be to create this instance in some initialization method, and just set the target position in this method.
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(getContext())
        {
            @Override
            public PointF computeScrollVectorForPosition(int targetPosition)
            {
                int yDelta = calculateCurrentDistanceToPosition(targetPosition);
                return new PointF(0, yDelta);
            }

            // This is the important method. This code will return the amount of time it takes to scroll 1 pixel.
            // This code will request X milliseconds for every Y DP units.
            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics)
            {
                return X / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, Y, displayMetrics);
            }

        };
        smoothScroller.setTargetPosition(position);

        startSmoothScroll(smoothScroller);
    }

在这个例子中,我使用了一个名为 "calculateCurrentDistanceToPosition" 的辅助方法。这可能有点棘手,因为它涉及跟踪您当前的滚动位置,并计算给定 y 位置的滚动位置。您可以找到一个示例,说明如何跟踪回收器的滚动条 y

计算给定位置的滚动 y 实际上取决于您的回收站显示的内容。假设您所有的项目都是相同的高度,您可以通过执行以下计算来计算:

targetScrollY = targetPosition * itemHeight

然后,要计算您需要滚动的距离,只需用目标滚动 y 减去当前滚动 y 即可:

private int calculateCurrentDistanceToPosition(int targetPosition) {
    int targetScrollY = targetPosition * itemHeight;
    return targetScrollY - currentScrollY;
}

2。正在减慢手动滚动速度。

再次,您需要编辑您的布局管理器,这次 - scrollVerticallyBy 方法:

    @Override
    public int scrollVerticallyBy(int delta, Recycler recycler, State state)
    {
       // write your limiting logic here to prevent the delta from exceeding the limits of your list.

       int prevDelta = delta;
       if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = (int)(delta > 0 ? Math.max(delta * MANUAL_SCROLL_SLOW_RATIO, 1) : Math.min(delta * MANUAL_SCROLL_SLOW_RATIO, -1));  

       // MANUAL_SCROLL_SLOW_RATIO is between 0 (no manual scrolling) to 1 (normal speed) or more (faster speed).
       // write your scrolling logic code here whereby you move each view by the given delta

        if (getScrollState() == SCROLL_STATE_DRAGGING)
            delta = prevDelta;

        return delta;
    }

编辑: 在上面的方法中,我调用了“getScrollState()”。这是RecyclerView的方法。在此实现中,我的自定义 LayoutManager 是我的自定义 RecyclerView 的嵌套 class。如果这对你不起作用,你可以尝试通过一些接口模式来获取滚动状态。

3。放慢投掷速度

在这里你想降低投掷速度。您将需要覆盖 RecyclerView subclass:

中的 fling 方法
@Override
public boolean fling(int velocityX, int velocityY)
{
     velocityY *= FLING_SCALE_DOWN_FACTOR; // (between 0 for no fling, and 1 for normal fling, or more for faster fling).

     return super.fling(velocityX, velocityY);
}

我很难提供更有针对性的解决方案,因为您没有 post 任何代码,也没有提供有关您的设置的大量信息,但我希望这涵盖了大多数基础并对您有所帮助找到最适合您的解决方案。

我只是简化回答如何使用它来控制平滑滚动。

创建Class

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;

public class CustomRecyclerView extends RecyclerView {

    Context context;

    public CustomRecyclerView(Context context) {
        super(context);
        this.context = context;
    }

    public CustomRecyclerView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomRecyclerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean fling(int velocityX, int velocityY) {

        velocityY *= 0.7;
        // velocityX *= 0.7; for Horizontal recycler view. comment velocityY line not require for Horizontal Mode.

        return super.fling(velocityX, velocityY);
    }

}

通过将 0.7 替换为您的值来调整速度。

现在像这样在你的 XML 中使用这个 class。

<<yourpackage>.CustomRecyclerView
    android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:scrollbars="vertical" />

在 Java 中阅读 RecyclerView。

CustomRecyclerView mRecyclerView;
mRecyclerView = (CustomRecyclerView) findViewById(R.id.my_recycler_view);

只需实施 LinearLayoutManager 的 smoothScrollToPosition()

LinearLayoutManager layoutManager = new LinearLayoutManager(this) {

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
        LinearSmoothScroller smoothScroller = new LinearSmoothScroller(this) {

            private static final float SPEED = 300f;// Change this value (default=25f)

            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return SPEED / displayMetrics.densityDpi;
            }

        };
        smoothScroller.setTargetPosition(position);
        startSmoothScroll(smoothScroller);
    }

};

使用它来平滑滚动

recyclerViewCart.isNestedScrollingEnabled = false