Center Aligning A RecyclerView Using LinearSmoothScroller

Nathan Sokalski 4,126 Reputation points
2021-05-11T21:24:27.04+00:00

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.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,326 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. JessieZhang-MSFT 7,706 Reputation points Microsoft Vendor
    2021-05-12T09:55:23.447+00:00

    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.