question

njsokalski avatar image
0 Votes"
njsokalski asked RobCaplan edited

LinearSmoothScroller & CalculateDtToFit: Item Larger Than RecyclerView

I have a RecyclerView which sometimes has an item that is larger (vertically) than the RecyclerView. I override the CalculateDtToFit method of a LinearSmoothScroller to adjust this by changing the parameters. Here is my LinearSmoothScroller:

 public class RoundSmoothScroller : LinearSmoothScroller
 {
     public RoundSmoothScroller(Context context) : base(context) { }
    
     public override int CalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference)
     {
         if (MainActivity.useroundsmoothscroll)
         {
             MainActivity.useroundsmoothscroll = false;
             if (this.TargetPosition == 0) { return base.CalculateDtToFit(viewStart, viewEnd, boxStart, boxEnd, LinearSmoothScroller.SnapToStart); }
             else if (this.TargetPosition == 1) { return base.CalculateDtToFit((int)(viewStart - 27 * Application.Context.Resources.DisplayMetrics.Density), viewEnd, boxStart, boxEnd, LinearSmoothScroller.SnapToStart); }
             else if (this.TargetPosition == MainActivity.Players[MainActivity.CurrentPlayerIndex].Scores.Count) { return base.CalculateDtToFit((int)(viewStart - (((MainActivity)Xamarin.Essentials.Platform.CurrentActivity).Cumulative ? 27 : 54) * Application.Context.Resources.DisplayMetrics.Density), (int)(viewStart + 54 * Application.Context.Resources.DisplayMetrics.Density), boxStart, boxEnd, LinearSmoothScroller.SnapToAny); }
             else { return base.CalculateDtToFit((int)(viewStart - (((MainActivity)Xamarin.Essentials.Platform.CurrentActivity).Cumulative ? 27 : 54) * Application.Context.Resources.DisplayMetrics.Density), (int)(viewStart + (((MainActivity)Xamarin.Essentials.Platform.CurrentActivity).Cumulative ? 81 : 108) * Application.Context.Resources.DisplayMetrics.Density), boxStart, boxEnd, LinearSmoothScroller.SnapToAny); }
         }
         else { return 0; }
     }
 }

However, it is still scrolling to the end of the original area rather than the values I pass when calling base.CalculateDtToFit. Why is it not scrolling to the area I specify?

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

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

Hello,​

Welcome to our Microsoft Q&A platform!

I used your code, And I met the same issue, my issue is related to create custom LinearLayoutManager

Firstly, you can add a breakpoint in the if (MainActivity.useroundsmoothscroll) this line, if blew code will be executed.

I make a test(move 3rd item to the center of recycleview), here is running screenshot.

https://imgur.com/a/MWPb5hH

Here is my step to achieve it.

  1. create a custom LinearLayoutManager

internal class MyLinearLayoutManager : LinearLayoutManager
    {
        private MainActivity mainActivity;

      

        public MyLinearLayoutManager(Context context) : base(context)
        {
            this.mainActivity = (MainActivity)context;
        }

       

        public override void SmoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position)
        {
        
            RoundSmoothScroller linearSmoothScroller = new RoundSmoothScroller(mainActivity);
            
            linearSmoothScroller.TargetPosition=position;
            StartSmoothScroll(linearSmoothScroller);
        }
    }


  1. Set custom LinearLayoutManager to mRecyclerView

mLayoutManager = new MyLinearLayoutManager(this);
            mRecyclerView.SetLayoutManager(mLayoutManager);


  1. achieve the RoundSmoothScroller .Here is my code(I test your )

public class RoundSmoothScroller : LinearSmoothScroller
    {
        public RoundSmoothScroller(Context context) : base(context) { }

        public override int CalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference)
        {
            if (MainActivity.useroundsmoothscroll)
            {
             //   MainActivity.useroundsmoothscroll = false;
                if (this.TargetPosition == 3) { return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2); } else { return 0; }
            }
            else { return 0; }
        }
    }


I test your (this.TargetPosition == 1) { return base.CalculateDtToFit((int)(viewStart - 27 * Application.Context.Resources.DisplayMetrics.Density), viewEnd, boxStart, boxEnd, LinearSmoothScroller.SnapToStart); } , it is worked like this screenshot.

Best Regards,

Leon Lu



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.


· 1
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.

@njsokalski did you add break point in the RoundSmoothScroller, when you execute mRecyclerView.SmoothScrollToPosition(index);, could this break point be executed? May I know whether your issue has been solved or not?

0 Votes 0 ·