How can i control the scrolling speed of recyclerView.smoothScrollToPosition(position)

前端 未结 5 592
感情败类
感情败类 2020-11-28 23:18

I have a recycler view... and i want a smooth scrolldown and then scrollup to it programatically to show the complete content in it to user .... And i m able to do this by<

相关标签:
5条回答
  • 2020-11-28 23:43

    Just to improve on the answer a little:

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

    And then set SpeedyLayoutManager to your RecyclerView:

    recyclerView.setLayoutManager(new SpeedyLinearLayoutManager(context, SpeedyLinearLayoutManager.VERTICAL, false);
    
    0 讨论(0)
  • 2020-11-28 23:54

    I've made a version that you can set the scrolling speed variable.

    If you set factor to 2, it will be twice as slow as default.

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-28 23:54

    I got it like this horizontally

      private val milliSecondsPerInch = 500f 
      var horizontalLayoutManager =  LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
    

    onCreate

    horizontalLayoutManager =  LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
    recycler_banner?.layoutManager = horizontalLayoutManager
    

    and then

    val linearSmoothScroller: LinearSmoothScroller =
    object : LinearSmoothScroller(this) {
        override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics): Float {
            return milliSecondsPerInch / displayMetrics.densityDpi
        }
    }
    linearSmoothScroller.targetPosition = 3 //the last position of the item in the list
    horizontalLayoutManager.startSmoothScroll(linearSmoothScroller)
    
    0 讨论(0)
  • 2020-11-28 23:56

    I found an answer!

    You need to make a custom class extending [LinearLayoutManager][1] and then override the [smoothScrollToPosition][1] method. Inside, you need to create a new [LinearSmoothScroller][1] and override its calculateSpeedPerPixel method Then use that LinearSmoothScroller to complete the scroll.

    Here is my example :

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

    Assign this CustomLinearLayoutManager to your RecyclerView and you should be good to go. Let me know if I was unclear in anything. I'll be happy to help.

    0 讨论(0)
  • 2020-11-29 00:01

    For those uninterested in overriding LinearLayoutManager (or whichever subclass you're using), you can just call startSmoothScroll(smoothScroller) directly on the layout manager.

    LinearSmoothScroller linearSmoothScroller = new LinearSmoothScroller(recyclerView.getContext()) {
    
        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return MILLISECONDS_PER_INCH / displayMetrics.densityDpi;
        }
    };
    
    linearSmoothScroller.setTargetPosition(position);
    layoutManager.startSmoothScroll(linearSmoothScroller);
    
    0 讨论(0)
提交回复
热议问题