question

njsokalski avatar image
0 Votes"
njsokalski asked RobCaplan edited

Center Aligning A RecyclerView Using LinearSmoothScroller

I have a Xamarin.Android app containing a RecyclerView for which I want to center items. I have created the following LinearSmoothScroller:
public class PlayerSmoothScroller : LinearSmoothScroller
{
public PlayerSmoothScroller(Context context) : base(context) { }
public override int CalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference)
{return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);}
}
When I use this, the items get scrolled farther than the edge, and completely into view, but are not quite centered. Here is a sample screenshot:
95656-screenshot-1620767861.png
In this screenshot, the yellow column should be centered, but it is not. I am new to customizing the scrolling, and exactly what the CalculateDtToFit parameters are, but the equation looks correct. Does it have something to do with when it calculates the widths of the columns? Is it related to the fact that not all the columns are the same width? Any help would be appreciated.

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

JessieZhang-2116 avatar image
0 Votes"
JessieZhang-2116 answered JessieZhang-2116 commented

Hello,


Welcome to our Microsoft Q&A platform!

If you want to scroll to the center item, you can use function ScrollToPosition to scroll to the special item. e.g.

 mLayoutManager = new LinearLayoutManager(this);
 mLayoutManager.ScrollToPosition(position);// position is the special position of your item in your RecyclerView 


Update:

I tested on my side using the following code, it works on my side:

1.create a class CenterSmoothScroller which implement interface LinearSmoothScroller

  public  class CenterSmoothScroller: LinearSmoothScroller
  {

     private Context mContext;

     private static float MILLISECONDS_PER_INCH = 100f;
     public CenterSmoothScroller(Context context) : base(context)
     {
         mContext = context;
     }

     public override int CalculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference)
     {
         return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
     }

     protected override float CalculateSpeedPerPixel(DisplayMetrics displayMetrics)
     {

         return MILLISECONDS_PER_INCH / (int)displayMetrics.DensityDpi;
     }
 }

And in activity:

         mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
         mLayoutManager = new LinearLayoutManager(this);
         mLayoutManager.Orientation = LinearLayoutManager.Horizontal;

         mRecyclerView.SetLayoutManager(mLayoutManager);
         mRecyclerView.GetLayoutManager().StartSmoothScroll(new CenterSmoothScroller(this) { TargetPosition = 3 });

The result is:

96233-image.png


Best Regards,


Jessie 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.



image.png (9.1 KiB)
· 2
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.

I think you misunderstood my question. The problem is not being able to see the item, it is about centering it (scrolling to the point where it is half way between the left & right edges). ScrollToPosition just scrolls it into view (therefore it ends up left or right aligned, or stays where it is if it is already visible). I also need to use one of the smooth scroll methods (instead of methods like ScrollToPosition) because I use an OnScrollListener to synchronize the scrolling, and it seems like only the smooth scroll methods trigger this. Here is the exact code I use to attempt to center an item:

 this.rvPlayerNames.GetLayoutManager().StartSmoothScroll(new PlayerSmoothScroller(Application.Context) { TargetPosition = MainActivity.CurrentPlayerIndex });
0 Votes 0 ·

I have updated my answer.You can check it.

0 Votes 0 ·