1. 程式人生 > >ScrollView仿微博詳情頁——輕鬆實現標題欄懸浮、漸變及Fragment內容切換

ScrollView仿微博詳情頁——輕鬆實現標題欄懸浮、漸變及Fragment內容切換

 作為一名熱愛學習的Android開發工程si,刷微博的時候居然還想著技術呢,覺得自己也是夠夠了........哈哈哈



 進入今天的正題,微博主頁大家肯定是看過的,先看一下微博的效果。
(小提示:該Demo是採用kotlin語言編寫的,需要配置Kotlin開發環境哦!)

微博的效果大家都看到了,先看看這標題欄懸停的效果。實現方式很多種,我的思路很簡單:頂部有一個預設隱藏的標題欄在上面,然後通過計算ScrollView向上滑動的距離,動態控制頭部標題導航欄的顯示隱藏。
簡單分析一下頁面佈局的結構:

頁面佈局程式碼:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/parent_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical">


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">


        <ScrollView
            android:id="@+id/scrollView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">


            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">


                <ImageView
                    android:id="@+id/iv_img"
                    android:layout_width="match_parent"
                    android:layout_height="200dp"
                    android:scaleType="fitXY"
                    android:src="@mipmap/bg_wb" />


                <include
                    android:id="@+id/ll_tab"
                    layout="@layout/layout_suspencial_title"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_below="@+id/iv_img"></include>


                <FrameLayout
                    android:id="@+id/fl_container"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_below="@+id/ll_tab"></FrameLayout>
            </RelativeLayout>
        </ScrollView>


        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">


            <TextView
                android:id="@+id/tv_title_text"
                android:layout_width="match_parent"
                android:layout_height="35dp"
                android:gravity="center"
                android:text="歌手李健"
                android:textColor="#ffffff"
                android:textSize="18sp" />


            <View
                android:id="@+id/title_divider"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_below="@+id/tv_title_text"
                android:background="#e6e6e6"
                android:visibility="gone"></View>
            <!--懸停導航標題欄-->
            <include
                android:id="@+id/ll_sus_tab"
                layout="@layout/layout_suspencial_title"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/title_divider"
                android:visibility="invisible"></include>
        </RelativeLayout>


    </FrameLayout>


</RelativeLayout>
設定標題欄導航欄懸停和標題欄漸變的核心程式碼:給ScrollView設定滑動的監聽
      scrollView.setOnScrollViewListener(object : MyScrollView.OnScrollViewListener {
            override fun onScrollChanged(scrollX: Int, scrollY: Int, oldx: Int, oldY: Int) {
                //如果向上滑動的距離>=iv_img.height - tv_title_text.height,隱藏的標題導航欄設定顯示
                var distanceScrollY = iv_img.height - tv_title_text.height
                if (scrollY >= distanceScrollY) {
                    ll_sus_tab.visibility = View.VISIBLE
//                    ll_tab.visibility = View.INVISIBLE
                    title_divider.visibility = View.VISIBLE
                } else {
                    ll_sus_tab.visibility = View.INVISIBLE
//                    ll_tab.visibility = View.VISIBLE
                    title_divider.visibility = View.GONE
                }
                //設定標題欄漸變
                if (scrollY <= 0) {
                    //初始位置:未滑動時,設定標題背景透明
                    tv_title_text.setBackgroundColor(Color.TRANSPARENT)
                    tv_title_text.setTextColor(Color.WHITE)
                } else if (scrollY > 0 && scrollY <= distanceScrollY) {
                    var scale: Float = (scrollY.toFloat()) / distanceScrollY
                    var alpha: Float = 255 * scale
                    tv_title_text.setBackgroundColor(Color.argb(alpha.toInt(), 255, 255, 255))
                    tv_title_text.setTextColor(Color.argb(alpha.toInt(), 0, 0, 0))
                } else {
                    tv_title_text.setBackgroundColor(Color.argb(255, 255, 255, 255))
                    tv_title_text.setTextColor(Color.argb(255, 0, 0, 0))
                }
//
            }
        })
最後實現的效果:

注意注意注意了:如果使用原生ScrollView,會報如下的警告,如果你是用API大於等於23(Android6.0)的手機測試,不會有什麼問題,程式正常執行。但是要是低於這個版本的手機,就會導致奔潰,報 java.lang.NoClassDefFoundError:


解決辦法很簡單,就是自定義一個ScrollView,寫一個介面將onScrollChange()暴露出去。

原始碼下載請戳:GitHub地址點選開啟連結