如何控制recyclerView.smoothScrollToPosition(位置)的滚动速度

Dip*_*ika 47 android android-recyclerview

我有一个回收者视图...我想要一个平滑的滚动,然后以编程方式滚动到它以向用户显示其中的完整内容....并且我能够通过以下方式执行此操作

    final int height=recyclerView.getChildAt(0).getHeight();
    recyclerView.smoothScrollToPosition(height);
    recyclerView.postDelayed(new Runnable() {
        public void run() {
            recyclerView.smoothScrollToPosition(0);
                        }
    },200);
Run Code Online (Sandbox Code Playgroud)

但我想要的是......减慢滚动速度,使整个内容清晰可见.所以,有人可以帮助我找到它.Thxs ...

Joe*_*her 90

只是为了改善答案:

public class SpeedyLinearLayoutManager extends LinearLayoutManager {

    private static final float MILLISECONDS_PER_INCH = 5f; //default is 25f (bigger = slower)

    public SpeedyLinearLayoutManager(Context context) {
        super(context);
    }

    public SpeedyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
        super(context, orientation, reverseLayout);
    }

    public SpeedyLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {

        final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {

            @Override
            public PointF computeScrollVectorForPosition(int targetPosition) {
                return super.computeScrollVectorForPosition(targetPosition);
            }

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

        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后将SpeedyLayoutManager设置为您的RecyclerView:

recyclerView.setLayoutManager(new SpeedyLinearLayoutManager(context, SpeedyLinearLayoutManager.VERTICAL, false);
Run Code Online (Sandbox Code Playgroud)

  • 这适用于横向.只需确保将SpeedyLinearLayoutManager.HORIZONTAL添加为SpeedyLinearLayoutManager构造函数的第二个参数. (3认同)
  • 我设置了私有静态最终浮点数MILLISECONDS_PER_INCH = 3000f,但没有任何速度差异观察.无论是25还是3000它是相同的速度.我已经检查了HORIZONTAL"SpeedyLinearLayoutManager(context,SpeedyLinearLayoutManager.HORIZONTAL,false)" (2认同)
  • 这是行不通的。水平方向使用! (2认同)

Dav*_*Liu 18

对于那些对重写LinearLayoutManager(或您正在使用的子类)不感兴趣的人,您可以startSmoothScroll(smoothScroller)直接在布局管理器上调用.

LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {

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

linearSmoothScroller.setTargetPosition(position);
layoutManager.startSmoothScroll(linearSmoothScroller);
Run Code Online (Sandbox Code Playgroud)


Jay*_* S. 16

我找到了答案!

您需要扩展自定义类[LinearLayoutManager][1],然后覆盖该[smoothScrollToPosition][1]方法.在里面,你需要创建一个新的[LinearSmoothScroller][1]并覆盖其calculateSpeedPerPixel方法然后用它LinearSmoothScroller来完成滚动.

这是我的例子:

public class CustomLinearLayoutManager extends LinearLayoutManager{
        @Override
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
            final LinearSmoothScroller linearSmoothScroller =
                    new LinearSmoothScroller(recyclerView.getContext()) {
                        private static final float MILLISECONDS_PER_INCH = 100f;

                        @Override
                        public PointF computeScrollVectorForPosition(int targetPosition) {
                            return CustomLinearLayoutManager.this
                                .computeScrollVectorForPosition(targetPosition);
                    }

                    @Override
                    protected float calculateSpeedPerPixel
                            (DisplayMetrics displayMetrics) {
                        return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
                    }
                };
        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }
}
Run Code Online (Sandbox Code Playgroud)

把它分配CustomLinearLayoutManager给你RecyclerView,你应该好好去.如果我对任何事情都不清楚,请告诉我.我很乐意提供帮助.


Boy*_*Boy 12

我已经制作了一个可以设置滚动速度变量的版本.

如果设置factor为2,则速度将是默认速度的两倍.

public class VariableScrollSpeedLinearLayoutManager extends LinearLayoutManager {

    private final float factor;

    public VariableScrollSpeedLinearLayoutManager(Context context, float factor) {
        super(context);
        this.factor = factor;
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {

        final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {

            @Override
            public PointF computeScrollVectorForPosition(int targetPosition) {
                return VariableScrollSpeedLinearLayoutManager.this.computeScrollVectorForPosition(targetPosition);
            }

            @Override
            protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
                return super.calculateSpeedPerPixel(displayMetrics) * factor;
            }
        };

        linearSmoothScroller.setTargetPosition(position);
        startSmoothScroll(linearSmoothScroller);
    }
}
Run Code Online (Sandbox Code Playgroud)


Pin*_*its 11

基于@Bartek Mrozinski 的回答。这是我的 Kotlin 扩展函数,用于在给定时间内平滑滚动 RecyclerView。

fun RecyclerView.smoothSnapToPosition(position: Int, snapMode: Int = LinearSmoothScroller.SNAP_TO_START) {
val scrollDuration = 500f;
val smoothScroller = object : LinearSmoothScroller(this.context) {
    override fun getVerticalSnapPreference(): Int = snapMode
    override fun getHorizontalSnapPreference(): Int = snapMode
    override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics?): Float {
        return scrollDuration / computeVerticalScrollRange();
    }
}
smoothScroller.targetPosition = position
layoutManager?.startSmoothScroll(smoothScroller) 
}
Run Code Online (Sandbox Code Playgroud)


小智 6

RecyclerView要在给定时间内平滑滚动,您可以覆盖LinearSmoothScroller#calculateSpeedPerPixel下面示例中的类似内容。

final Context context = getContext();
final RecyclerView recyclerView = new RecyclerView(context);

final LinearLayoutManager layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);

final YourCustomAdapter adapter = new YourCustomAdapter();
recyclerView.setAdapter(new YourCustomAdapter());

final float scrollDuration = 30000f; // in milliseconds
final LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
    @Override
    protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
        return scrollDuration / recyclerView.computeVerticalScrollRange();
    }
};

linearSmoothScroller.setTargetPosition(adapter.getItemCount() - 1);
layoutManager.startSmoothScroll(linearSmoothScroller);
Run Code Online (Sandbox Code Playgroud)