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