question

AnthonyWicks-2244 avatar image
0 Votes"
AnthonyWicks-2244 asked RobCaplan edited

Variable speed scrolling of recyclerview

Hi. (Apologies for the length of this question!)

The Android app I'm writing (Xamarin, Visual Studio 2019) displays gallery pictures in a recyclerview. I want it to scroll that list by tilting the phone, and so far I achieve this by using ScrollBy on a timer - every 20MS it scrolls a variable number of pixels depending on how steep the tilt is. That works pretty well except that at slow speeds there is a noticeable pause whenever a new image appears on screen. I've tried a couple of things to fix it; suppressing the images (for which I use Glide), and invoking GetExtraLayoutSpace in the LayoutManager, but no luck.

The way I'd like to do it is to control the scroll speed as the scrolling is taking place - that way I could just do one SmoothScrollToPosition to the bottom (with speed set to very slow) and speed it up as the tilt got steeper. But as I understand it the method CalculateSpeedPerPixel only gets called once for each use of the SmoothScroller and the value cached - so the value it gives can't be changed 'on the fly'.

dotnet-xamarin
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

JarvanZhang-MSFT avatar image
0 Votes"
JarvanZhang-MSFT answered JarvanZhang-MSFT commented

Hello,​

Welcome to our Microsoft Q&A platform!

The way I'd like to do it is to control the scroll speed as the scrolling is taking place - that way I could just do one SmoothScrollToPosition to the bottom

To customize the speed of SmoothScrollToPosition command, try creating a custom LinearSmoothScroller class to rewrite the CalculateSpeedPerPixel method to define the value fo the speed. Then custom a custom LinearLayoutManager class and pass the custom scroller to the manager.

Here is the related code, you could refer to it.

public class CustomLayoutManager : LinearLayoutManager
{
    public CustomLayoutManager(Context context) : base(context)
    {
    }
    public CustomLayoutManager(IntPtr handle, JniHandleOwnership transfer) : base(handle, transfer)
    {
    }
    public CustomLayoutManager(Context context, int orientation, bool reverseLayout) : base(context, orientation, reverseLayout)
    {
    }
    public CustomLayoutManager(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
    }
    public override void SmoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position)
    {
        CustomScroller scroller = new CustomScroller(recyclerView.Context, ScrollDuration, recyclerView);

        scroller.TargetPosition = position;
        StartSmoothScroll(scroller);
    }
    private float ScrollDuration = 30000f;
    void setDuration(float duration)
    {
        ScrollDuration = duration;
    }
}

public class CustomScroller : LinearSmoothScroller
{
    private float ScrollDuration;
    private RecyclerView recyclerView;
    public CustomScroller(Context context, float scrollDuration, RecyclerView recyclerView) : base(context)
    {
        ScrollDuration = scrollDuration;
    }

    public override PointF ComputeScrollVectorForPosition(int targetPosition)
    {
        return base.ComputeScrollVectorForPosition(targetPosition);
    }

    protected override float CalculateSpeedPerPixel(DisplayMetrics displayMetrics)
    {
        return ScrollDuration / recyclerView.ComputeVerticalScrollRange();
    }
}


Best Regards,

Jarvan Zhang


If the response is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


· 5
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Jarvan Zhang thanks for your quick response. I did already try something similar but perhaps didn't do it right.

Anyway I'll play around with your suggestion over the next couple of days and come back with a fuller reply.

And I shall accept your answer

0 Votes 0 ·

Jarvan Zhang, thanks for your quick response. I'll play around with your suggestion over the next couple of days (I'm tied up with other stuff right now) and get back to you.

Regards

Tony Wicks

0 Votes 0 ·

Jarvan Zhang I have now had time to play with this and it works perfectly.

Thanks again.

0 Votes 0 ·

It's my pleasure. Happy coding!

0 Votes 0 ·

Hi Jarvan Zhang.

I had to deviate slightly from your code in that I had to set the interpolator to null to avoid the error message "if you provide an interpolator..." but once I figured out how to do that your method works perfectly.

Thanks again.

0 Votes 0 ·