RecyclerView与TabLayout的滚动定位

(转载请注明出处)
最近项目有个需求,RecyclerView+TabLayout联动,点击随意一个tab标签,指定RecyclerView定位到对应位置,滑动RecyclerView,让tab跳到相应的标签。先上图

这个是点击tab的
RecyclerView与TabLayout的滚动定位
文章图片

这个是滑动recyclerview的,嗯,大体就这样。
现在,我们先一条一条分析,首先,recyclerview的滚动到指定一个的位置,也就是我们的锚点。这里我使用的recyclerview里的

manager.scrollToPositionWithOffset(str1[pos], 0);

这是LinearLayoutManager的

scrollToPositionWithOffset(int position, int offset)

方法。这个方法可以将item滚动到指定位置并置顶,offset默认是0,表示 Item 移动到第一项后跟 RecyclerView 上边界或下边界之间的距离。 滚动到锚点的方法有四种,具体的可以看这篇文章 https://www.jianshu.com/p/3acc395ae933,感谢。
然后,是TabLayout的设置位置,
tabLayout.setScrollPosition(pos, 0f, true);

setScrollPosition(int position, float positionOffset, boolean updateSelectedText)

positionOffset是偏移量,0-1,默认为0f,(若为1f,即你默认选的第0个tab,它会向右偏移一个单位,变为1,)
updateSelectedText布尔值,表示移动后位置所对应的Tab为选中状态,true选中,false,不选中。
最后,就是逻辑了,也算最关键的一点了,滑动列表时,tab动态改变。
recyclerview的滑动方法,(使用add,set的已经过时了)
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()

逻辑在onScrolled方法里(不写在onScrollStateChanged是因为这个方法里不是实时更新tab的,)
@Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //这个主要是recyclerview滑动时让tab定位的方法 if (isScrolled) { int top = manager.findFirstVisibleItemPosition(); int bottom = manager.findLastVisibleItemPosition(); int pos = 0; if (bottom == list.size() - 1) { //先判断滑到底部,tab定位到最后一个 pos = str1.length - 1; } else if (top == str1[str1.length - 1]) { //如果top等于指定的位置,对应到tab即可, pos = str1[str1.length - 1]; } else { //循环遍历,需要比较i+1的位置,所以循环长度要减1, //如果 i str1[i] && top < str1[i + 1]) { pos = i; break; } } }//设置tab滑动到第pos个 tabLayout.setScrollPosition(pos, 0f, true); }}

我的逻辑,
1.首先,获取到当前可见的列表最上top和最下项bottom,
2.先判断是否滑到底部,已经到底,则tab直接设置最后一项,
3.使用top判断在哪个区间,for循环区间, 如果,a≤top≤a+1,则当前是在第a项标签,即tab标签选中第a项。
在此,for循环时需要比较第a+1项,所以长度要 -1,防止越界,然后先判断最后一项。
还有,大家应该注意到有个参数 isScrolled,作用是在滑动时点击标签不生效。
(大家应该发现点击tab时,position=8,=9时候没有变化,是因为已经到底部了,)
demo我已上传github,欢迎大家下载,希望能帮到大家 ^-^()
https://github.com/qq675080677/RecyclerViewAnchor
【RecyclerView与TabLayout的滚动定位】

    推荐阅读