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

我正在使用CardView的RecyclerView。 我知道如何控制列表视图的速度。 但不是回收站。

我在search类名称SmoothScroll中search了很多。 如何使用? 我不知道! 现在RecyclerView的默认滚动速度很快。

更新:

我总结了吉尔回答这个

当你说“ smoothScroll ”时,你的意思还不清楚。 你可能会指自动的“ smoothScrollToPosition ”,它会自动滚动到指定的位置,你可能会谈论手动滚动,你可能会在谈论扔。 为了繁荣,我现在试图回答所有这些问题。

1.自动平滑滚动。

在您的布局pipe理器中,您需要实现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位置的滚动位置。 您可以在这里find一个如何跟踪回收商滚动的例子。

计算一个给定位置的滚动值真的取决于你的回收站显示的内容。 假设所有项目的高度相同,可以通过执行以下计算来计算:

 targetScrollY = targetPosition * itemHeight 

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

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

2.减慢手动滚动。

再一次,你需要编辑你的布局pipe理器,这次是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的嵌套类。 如果这不适合你,你可以尝试通过一些接口模式来获取滚动状态。

3.减慢投掷速度

在这里,你想要降低一下速度。 您需要重写RecyclerView子类中的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); } 

由于您没有发布任何代码或提供有关您的设置的许多信息,因此我很难提供更加定制的解决scheme,但我希望这涵盖了大多数的基础知识,并将帮助您find最适合您的解决scheme。

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

创build类

 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.7replace为您的值来调整速度。

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

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