首先看效果
先說關鍵點
- 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(); } } }