一、需求:
項(xiàng)目開發(fā)中的需求,需要scrollview和tablayout實(shí)現(xiàn)聯(lián)動(dòng):
1、點(diǎn)擊tablayout的tab,scrollview滑動(dòng)到指定的位置
2、scrollview滑動(dòng)到某位置時(shí)tablayout切換到對(duì)應(yīng)的tab
效果如下:

效果.gif
二、開始擼代碼
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabIndicatorColor="@color/colorPrimary"
app:tabMode="fixed"
app:tabSelectedTextColor="@color/colorPrimary"
app:tabTextColor="@android:color/black">
<com.google.android.material.tabs.TabItem
android:id="@+id/tab1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按鈕1" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tab2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按鈕2" />
<com.google.android.material.tabs.TabItem
android:id="@+id/tab3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="按鈕3" />
</com.google.android.material.tabs.TabLayout>
<androidx.core.widget.NestedScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是按鈕1" />
<TextView
android:layout_width="match_parent"
android:layout_height="800dp"
android:background="@android:color/holo_blue_dark" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是按鈕2" />
<TextView
android:layout_width="match_parent"
android:layout_height="800dp"
android:background="@android:color/holo_green_light" />
<TextView
android:id="@+id/tv3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是按鈕3" />
<TextView
android:layout_width="match_parent"
android:layout_height="800dp"
android:background="@android:color/holo_red_dark" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
java:
private int tabIndex = 0;//tablayout所處的下標(biāo)
private boolean scrollviewFlag = false;//標(biāo)記是否是scrollview在滑動(dòng)
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
if (!scrollviewFlag) {
switch (tab.getPosition()) {
case 0://scrollview移動(dòng)到tv1的頂部坐標(biāo)處
scrollView.scrollTo(0, tv1.getTop());
break;
case 1://scrollview移動(dòng)到tv2的頂部坐標(biāo)處
scrollView.scrollTo(0, tv2.getTop());
break;
case 2://scrollview移動(dòng)到tv3的頂部坐標(biāo)處
scrollView.scrollTo(0, tv3.getTop());
break;
}
}
//用戶點(diǎn)擊tablayout時(shí),標(biāo)記不是scrollview主動(dòng)滑動(dòng)
scrollviewFlag = false;
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
//scrollview滑動(dòng)事件監(jiān)聽
scrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
scrollviewFlag = true;
tabIndex = tabLayout.getSelectedTabPosition();
if (scrollY < tv2.getTop()) {
if (tabIndex != 0) {//增加判斷,如果滑動(dòng)的區(qū)域是tableIndex=0對(duì)應(yīng)的區(qū)域,則不改變tablayout的狀態(tài)
tabLayout.selectTab(tabLayout.getTabAt(0));
}
} else if (scrollY >= tv2.getTop() && scrollY < tv3.getTop()) {
if (tabIndex != 1) {
tabLayout.selectTab(tabLayout.getTabAt(1));
}
} else if (scrollY >= tv3.getTop()) {
if (tabIndex != 2) {
tabLayout.selectTab(tabLayout.getTabAt(2));
}
}
scrollviewFlag = false;
}
});
大概邏輯在代碼的注解上
注:僅以記錄學(xué)習(xí)使用,如有錯(cuò)誤,歡迎指出,互相學(xué)習(xí)