How to sync scrolling first-positions of 2 RecyclerViews?

后端 未结 4 1941
情话喂你
情话喂你 2021-01-01 21:21

Background

I have 2 RecyclerView instances. One is horizontal, and the second is vertical.

They both show the same data and have the same amount of items,

4条回答
  •  礼貌的吻别
    2021-01-01 22:11

    1-) Layout manager

    The current smoothScrollToPosition does not take the element to the top. So let's write a new layout manager. And let's override this layout manager's smoothScrollToPosition.

    public class TopLinearLayoutManager extends LinearLayoutManager
    {
        public TopLinearLayoutManager(Context context, int orientation)
        {
            //orientation : vertical or horizontal
            super(context, orientation, false);
        }
    
        @Override
        public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position)
        {
            RecyclerView.SmoothScroller smoothScroller = new TopSmoothScroller(recyclerView.getContext());
            smoothScroller.setTargetPosition(position);
            startSmoothScroll(smoothScroller);
        }
    
        private class TopSmoothScroller extends LinearSmoothScroller
        {
            TopSmoothScroller(Context context)
            {
                super(context);
            }
    
            @Override
            public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference)
            {
                return (boxStart - viewStart);
            }
        }
    }
    

    2-) Setup

        //horizontal one
        RecyclerView rvMario = (RecyclerView) findViewById(R.id.rvMario);
    
        //vertical one
        RecyclerView rvLuigi = (RecyclerView) findViewById(R.id.rvLuigi);
    
        final LinearLayoutManager managerMario = new LinearLayoutManager(MainActivity.this, LinearLayoutManager.HORIZONTAL, false);
        rvMario.setLayoutManager(managerMario);
        ItemMarioAdapter adapterMario = new ItemMarioAdapter(itemList);
        rvMario.setAdapter(adapterMario);
    
         //Snap to start by using Ruben Sousa's RecyclerViewSnap
        SnapHelper snapHelper = new GravitySnapHelper(Gravity.START);
        snapHelper.attachToRecyclerView(rvMario);
    
        final TopLinearLayoutManager managerLuigi = new TopLinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL);
        rvLuigi.setLayoutManager(managerLuigi);
        ItemLuigiAdapter adapterLuigi = new ItemLuigiAdapter(itemList);
        rvLuigi.setAdapter(adapterLuigi);
    

    3-) Scroll listener

    rvMario.addOnScrollListener(new RecyclerView.OnScrollListener()
    {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy)
        {
         super.onScrolled(recyclerView, dx, dy);
    
         //get firstCompleteleyVisibleItemPosition
         int firstCompleteleyVisibleItemPosition = managerMario.findFirstCompletelyVisibleItemPosition();
    
         if (firstCompleteleyVisibleItemPosition >= 0)
         {  
          //vertical one, smooth scroll to position
          rvLuigi.smoothScrollToPosition(firstCompleteleyVisibleItemPosition);
         }
        }
    
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState)
        {
         super.onScrollStateChanged(recyclerView, newState);
        }
    });
    

    4-) Output

提交回复
热议问题