Home » Android » java – How to sync TabLayout with Recyclerview?

java – How to sync TabLayout with Recyclerview?

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a TabLayout with Recyclerview so that when tabs are clicked then the Recyclerview is scrolled to a particular position.
I want the reverse procedure as well such that when the Recyclerview is scrolled to a particular position then the particular tab is highlighted.

For example: If there are 4 tabs in the TabLayout and when Recyclerview is scrolled to 5th position(Item visible and below TabLayout) then 3rd tab should be highlighted.enter image description here

Here when ‘How it works’ appears below TabLayout then tabs ‘How it works’ should be highlighted.

How to&Answers:

Try this

follow this steps

  1. Add a ScrollListener to your RecyclerView
  2. than find first visible item of your RecyclerView
  3. set the select the tab in TabLayout as per position of your RecyclerView

SAMPLE CODE

    myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            int itemPosition=linearLayoutManager.findFirstCompletelyVisibleItemPosition();

            if(itemPosition==0){ //  item position of uses
                TabLayout.Tab tab = myTabLayout.getTabAt(Index);
                tab.select();
            }else if(itemPosition==1){//  item position of side effects 
                TabLayout.Tab tab = myTabLayout.getTabAt(Index);
                tab.select();
            }else if(itemPosition==2){//  item position of how it works
                TabLayout.Tab tab = myTabLayout.getTabAt(Index);
                tab.select();
            }else if(itemPosition==3){//  item position of precaution 
                TabLayout.Tab tab = myTabLayout.getTabAt(Index);
                tab.select();
            }
        }
    });

EDIT

public class MyActivity extends AppCompatActivity {


    RecyclerView myRecyclerView;
    TabLayout myTabLayout;
    LinearLayoutManager linearLayoutManager;
    ArrayList<String> arrayList = new ArrayList<>();
    DataAdapter adapter;
    private boolean isUserScrolling = false;
    private boolean isListGoingUp = true;




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        myTabLayout = findViewById(R.id.myTabLayout);



        myRecyclerView = findViewById(R.id.myRecyclerView);
        linearLayoutManager = new LinearLayoutManager(this);
        myRecyclerView.setLayoutManager(linearLayoutManager);
        myRecyclerView.setHasFixedSize(true);

        for (int i = 0; i < 120; i++) {
            arrayList.add("Item " + i);
        }

        adapter= new DataAdapter(this,arrayList);
        myRecyclerView.setAdapter(adapter);

        myTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                isUserScrolling = false ;
                int position = tab.getPosition();
                if(position==0){
                    myRecyclerView.smoothScrollToPosition(0);
                }else if(position==1){
                    myRecyclerView.smoothScrollToPosition(30);
                }else if(position==2){
                    myRecyclerView.smoothScrollToPosition(60);
                }else if(position==3){
                    myRecyclerView.smoothScrollToPosition(90);
                }
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {

            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
        myRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    isUserScrolling = true;
                    if (isListGoingUp) {
                        //my recycler view is actually inverted so I have to write this condition instead
                        if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == arrayList.size()) {
                            Handler handler = new Handler();
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    if (isListGoingUp) {
                                        if (linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == arrayList.size()) {
                                            Toast.makeText(MyActivity.this, "exeute something", Toast.LENGTH_SHORT).show();
                                        }
                                    }
                                }
                            }, 50);
                            //waiting for 50ms because when scrolling down from top, the variable isListGoingUp is still true until the onScrolled method is executed
                        }
                    }
                }

            }
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int itemPosition = linearLayoutManager.findFirstVisibleItemPosition();


                if(isUserScrolling){
                    if (itemPosition == 0) { //  item position of uses
                        TabLayout.Tab tab = myTabLayout.getTabAt(0);
                        tab.select();
                    } else if (itemPosition == 30) {//  item position of side effects
                        TabLayout.Tab tab = myTabLayout.getTabAt(1);
                        tab.select();
                    } else if (itemPosition == 60) {//  item position of how it works
                        TabLayout.Tab tab = myTabLayout.getTabAt(2);
                        tab.select();
                    } else if (itemPosition == 90) {//  item position of precaution
                        TabLayout.Tab tab = myTabLayout.getTabAt(3);
                        tab.select();
                    }
                }



            }
        });


    }


}

Answer:

private fun syncTabWithRecyclerView() {

        // Move recylerview to the position selected by user
        menutablayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab) {
                if (!isUserScrolling) {
                    val position = tab.position
                    linearLayoutManager.scrollToPositionWithOffset(position, 0)
                }


            }

            override fun onTabUnselected(tab: TabLayout.Tab) {

            }

            override fun onTabReselected(tab: TabLayout.Tab) {
            }
        })

        // Detect recyclerview position and select tab respectively.
        menuRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    isUserScrolling = true
                }  else if (newState == RecyclerView.SCROLL_STATE_IDLE) 
                    isUserScrolling = false
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (isUserScrolling) {
                    val itemPosition = linearLayoutManager.findLastVisibleItemPosition()
                    val tab = menutablayout.getTabAt(itemPosition)
                    tab?.select()
                }
            }
        })
    }