android使用TabLayout+NestedScrollView 實現詳情介面tab頁 關聯 上下滑動檢視的效果

JavPer發表於2020-11-28

需求

最近有需求要實現商品詳情介面,比較常見的就是那種頭部是Tab頁,下面是滑動檢視,具體效果類似下圖:
在這裡插入圖片描述
當選中頭部某個tab,下部檢視滑動到具體內容,或者檢視滑動到某具體內容時,tab頁自動選中某tab。現在實現這種效果很簡單的,做個簡單總結。

實現

這裡使用TabLayout+NestedScrollView ,TabLayout負責頭部tab,NestedScrollView 負責介面上下滑動的檢視。如下部分程式碼:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    >
    <androidx.core.widget.NestedScrollView
        android:id="@+id/mainScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <View
                    android:id="@+id/oneStartView"
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:visibility="invisible"
                    />
            </LinearLayout>
           <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <View
                    android:id="@+id/twoStartView"
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:visibility="invisible"
                    />
            </LinearLayout>
             <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                >
                <View
                    android:id="@+id/threeStartView"
                    android:layout_width="match_parent"
                    android:layout_height="1px"
                    android:visibility="invisible"
                    />
            </LinearLayout>   
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
    <com.google.android.material.tabs.TabLayout
        android:id="@+id/goodsDetailsTabLayout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_30"
        android:background="@color/translucent"
        app:tabIndicatorColor="@color/cash_gift_font_red"
        app:tabIndicatorFullWidth="false"
        app:tabIndicatorHeight="@dimen/dp_2"
        app:tabRippleColor="@color/translucent"
        app:tabSelectedTextColor="@color/black_font_color"
        app:tabTextAppearance="@style/music_tabLayout_text"
        android:visibility="gone"
        app:tabTextColor="@color/black_font_color">
        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="商品" />
        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="詳情" />
        <com.google.android.material.tabs.TabItem
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="店鋪" />
    </com.google.android.material.tabs.TabLayout>
</FrameLayout>

檢視佈局好以後,具體控制程式碼 大致如下:

goodsDetailsTabLayout!!.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabSelected(tab: TabLayout.Tab) {
                when (tab.position) {
                    Int_ZREO -> {
                        mainScrollView.smoothScrollTo(0,30)
                    }
                    Int_ONE -> {
                        mainScrollView.smoothScrollTo(0,twoStartView.y.toInt())
                    }
                    Int_THREE ->{
                        mainScrollView.smoothScrollTo(0,threeStartView.y.toInt())
                    }
                }
            }

            override fun onTabUnselected(tab: TabLayout.Tab) {}
            override fun onTabReselected(tab: TabLayout.Tab) {}
        })

上面是通過addOnTabSelectedListener實現選中tab,檢視滑動到某塊內容位置。
下面是通過setOnScrollChangeListener實現滑動檢視時觸發 選中某類tab 。

 mainScrollView.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->
            when {
                scrollY < 30 -> {
                    goodsDetailsTabLayout.visibility = View.GONE
                }
                scrollY < oneStartView.y.toInt() -> {
                    goodsDetailsTabLayout.visibility = View.VISIBLE
                    goodsDetailsTabLayout!!.selectTab(goodsDetailsTabLayout!!.getTabAt(0))
                    goodsDetailsTabLayout!!.setScrollPosition(0, 0f, true)
                }
                scrollY > twoStartView.y.toInt() -> {
                    goodsDetailsTabLayout.visibility = View.VISIBLE
                    goodsDetailsTabLayout!!.selectTab(goodsDetailsTabLayout!!.getTabAt(1))
                    goodsDetailsTabLayout!!.setScrollPosition(1, 0f, true)
                }
                scrollY > threeStartView.y.toInt() -> {
                    goodsDetailsTabLayout.visibility = View.VISIBLE
                    goodsDetailsTabLayout!!.selectTab(goodsDetailsTabLayout!!.getTabAt(2))
                    goodsDetailsTabLayout!!.setScrollPosition(2, 0f, true)
                }
            }
        })

以上就是使用TabLayout+NestedScrollView 實現詳情介面tab頁 關聯 上下滑動檢視的效果,程式碼都是抽離出來的,大致如上。

相關文章