首先看效果
先说关键点
- tabLayout选中的时候滑动到指定锚点
- 由scrollview主动引起的滑动,滑动的指定区域,选中那个指定tabLayout
- 由于上述两个步骤会引起相互调用,所以要判断scrollview滑动是主动引起的还是点击tabLayout引起的,涉及到利用反射给tabLayout的tab添加onClick点击监听
项目中的LinearLayout的子元素之间的分隔符用到了系统提供的以下属性
android:showDividers="middle|end"
android:divider="@drawable/divider_item"
- 使用方法给百度LinearLayout分隔符
部分代码
-
关键点1代码
tab_layout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { @Override public void onTabSelected(TabLayout.Tab tab) { int position = tab.getPosition(); int top = 0; switch (position) { case 0: top = ll_first.getTop(); break; case 1: top = ll_second.getTop(); break; case 2: top = ll_third.getTop(); break; } //关键点1:点击tab滑动页面到指定位置,利用scrollView的smoothScrollTo方法 if (!isScroll) {//如果是点击tabLayout //因为用户滑动页面也会导致tab选中,这里避开这种情况 scrollview.smoothScrollTo(0, top); } }
-
关键点2代码
scrollview.setCallbacks(new CustomScrollView.Callbacks() { @Override public void onScrollChanged(int x, int y, int oldx, int oldy) { if (isScroll) { //关键点2:由scrollView引起的滑动后移动tabLayout高亮显示指定的tab if (y < ll_second.getTop()) { setScrollPos(0); } else if (y >= ll_second.getTop() && y < ll_third.getTop()) { setScrollPos(1); } else if (y >= ll_third.getTop()) { setScrollPos(2); } } } }); private void setScrollPos(int newPos) { if (lastPos != newPos) { //此方法可能会导致scrollview的二次滑动,所以要在onTabSelected事件中要判断是不是由scrollview主动引起的滑动 tab_layout.getTabAt(newPos).select(); //此方法只是从表面上选中了tab选项,实际tab_layout.getTabAt(0).isSelected()返回值仍可能是false,导致有时候点击tab页面不会滑动到指定锚点 // tab_layout.setScrollPosition(newPos,0,true); } lastPos = newPos; }
-
关键点3代码
public static void addClick(final TabLayout tabLayout, final OnTabClickListener listener){ for (int i = 0; i < tabLayout.getTabCount(); i++) { TabLayout.Tab tab = tabLayout.getTabAt(i); if (null == tab) return; // 这里使用到反射,拿到Tab对象后获取Class Class c = tab.getClass(); try { // Filed “字段、属性”的意思,c.getDeclaredField 获取私有属性。 // "view"是Tab的私有属性名称(可查看TabLayout源码8.0以上),类型是 TabView,TabLayout私有内部类。 //8.0以下是mView Field field = null; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ //8.0及以上手机 field = c.getDeclaredField("view"); }else { field = c.getDeclaredField("mView"); } field.setAccessible(true); final View view = (View) field.get(tab); if (null == view) return; view.setTag(i); view.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onClick(tabLayout,v); } }); } catch (Exception e) { e.printStackTrace(); } } }
来源:CSDN
作者:parade岁月
链接:https://blog.csdn.net/parade0393/article/details/104144941