Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sync TabLayout with Recyclerview?

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.

like image 408
Prithvi Bhola Avatar asked Aug 06 '18 06:08

Prithvi Bhola


People also ask

Does Viewpager use RecyclerView?

Since ViewPager2 makes use of RecyclerView as adapter to show items we can customize it's performance and design in many ways. We can make use of DiffUtils, layout direction such as right-to left, both vertical and horizontal direction to show items, PageTransformations etc.

How do you make a page indicator for horizontal RecyclerView?

You can add an indicator by using RecyclerView. ItemDecoration. Just draw some lines or circles at the bottom and use layoutManager. findFirstVisibleItemPosition() to get the current active item.


1 Answers

I figured you don't even need those flags and it was enough to override RecyclerView's onScrolled and select tab and scroll to position when tab is selected and that Tab wasn't already selected:

override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
     val llm = recyclerView.layoutManager as LinearLayoutManager

     // depending on sections'heights one may want to add more logic 
     // on how to determine which section to scroll to
     val firstCompletePos = llm.findFirstCompletelyVisibleItemPosition()

     if (firstCompletePos != tabLayout.selectedTabPosition)
         tabLayout.getTabAt(firstCompletePos)?.select()
}

Then I have a TextView which is set as customView to tabLayout:

tabLayout.addTab(newTab().also { tab ->
         tab.customView = AppCompatTextView(context).apply {
             // set layout params match_parent, so the entire section is clickable
             // set style, gravity, text etc.
             setOnClickListener { 
                tabLayout.selectTab(tab)

                recyclerView.apply {
                    val scrollTo = tabLayout.selectedTabPosition
                    smoothScrollToPosition(scrollTo)
                }
             }
          }
})

With this setup you have:

  1. Tab selected when user both scrolls and flings
  2. RecyclerView is scrolled when user clicks on the tab.
like image 144
Yurets Avatar answered Sep 28 '22 03:09

Yurets