序
昨晚經歷了美股本月的第三次熔斷 ,有史以來的第四次熔斷 。
突 。 突突 。。突突突 。。。
很尷尬 ,找不到做 gif 的東西 。怎麼辦呢 。(找了好久 ,在手機上下載了一個 GIF 動圖製作)
AppbarLayout 回顧
我記得 16 、17年的時候這個效果在很多 APP 上都有出現 。之前寫過demo ,然後一直也沒機會在項目中使用 。
實現類似的效果 ,主要是使用三個控件相結合 CoordinatorLayout 、AppbarLayout 、NestedScrollView 。
AppbarLayout 是一種支持響應滾動手勢的 app bar 佈局 , CollapsingToolbarLayout 則是專門用來實現子佈局內不同元素響應滾動細節的佈局 。與 AppbarLayout 組合的滾動佈局 (RecyclerView, NestedScrollView等) , 需要設置 app:layout_behavior = "@strng/appbar_scrolling_view_behavior" 。 沒有設置的話 , AppbarLayout 將不會響應滾動佈局的滾動事件 。
簡單的效果代碼
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
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"
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:title="Title" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<TextView
android:id="@+id/tv_content"
android:layout_margin="16dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:lineSpacingMultiplier="2"
/>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
效果如下
- 隨着文本往上滾動, 頂部的toolbar也往上滾動, 直到消失.
- 隨着文本往下滾動, 一直滾到文本的第一行露出來, toolbar也逐漸露出來
AppBarLayout 繼承自LinearLayout,佈局方向爲垂直方向。所以你可以把它當成垂直佈局的LinearLayout來使用。AppBarLayout是在LinearLayou上加了一些材料設計的概念,它可以讓你定製當某個可滾動View的滾動手勢發生變化時,其內部的子View實現何種動作。
我們可以通過給Appbar下的子View添加app:layout_scrollFlags來設置各子View執行的動作. scrollFlags可以設置的動作如下:
- scroll: 值設爲scroll的View會跟隨滾動事件一起發生移動。就是當指定的ScrollView發生滾動時,該View也跟隨一起滾動,就好像這個View也是屬於這個ScrollView一樣。
- enterAlways: 值設爲enterAlways的View,當任何時候ScrollView往下滾動時,該View會直接往下滾動。而不用考慮ScrollView是否在滾動到最頂部還是哪裏.
- exitUntilCollapsed:值設爲exitUntilCollapsed的View,當這個View要往上逐漸“消逝”時,會一直往上滑動,直到剩下的的高度達到它的最小高度後,再響應ScrollView的內部滑動事件。
- enterAlwaysCollapsed:是enterAlways的附加選項,一般跟enterAlways一起使用,它是指,View在往下“出現”的時候,首先是enterAlways效果,當View的高度達到最小高度時,View就暫時不去往下滾動,直到ScrollView滑動到頂部不再滑動時,View再繼續往下滑動,直到滑到View的頂部結束 。
參考 :https://www.jianshu.com/p/bbc703a0015e
PS:更多的細節可以查看文章鏈接 。
實現項目效果
可以回到文章頂部在看一下項目要求的效果 。
頂部是四個 Tab ,下面是 ViewPager + Fragment + RecyclerView 。如果在加上懸浮效果的話 ,那這個頁面結構是 CoordinatorLayout + AppBarLayout + TabLayout + ViewPager + Fragment + RecyclerView 。
1. XML 佈局
<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:background="@color/white"
android:orientation="vertical">
<include layout="@layout/actionbar_title_back" />
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:elevation="0dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="@dimen/dp_56"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<ImageView
android:id="@+id/iv_image"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_128"
android:scaleType="centerCrop"
android:src="@drawable/bg_classroom_tab"
app:layout_constraintTop_toTopOf="parent" />
<net.lucode.hackware.magicindicator.MagicIndicator
android:id="@+id/magic_indicator"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_106"
android:layout_marginTop="@dimen/dp_10"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
可以看到 AppBarLayout 裏面包含的佈局是 ConstraintLayout 。
PS :一定要設置 ConstraintLayout 的 app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" 屬性 。 **
PS1: ConstraintLayout 一定要給個 android:minHeight="@dimen/dp_56" 最小高度 。 **
(可以自己多設置幾次 ,感受一下其中的變化)
接下來就是ViewPager 的 layout_behavior 屬性 。
PS:一定要設置 ,負責會覆蓋佈局 。
難點應該是 ConstraintLayout 的 app:layout_scrollFlags 屬性和 android:minHeight 屬性 。
代碼已經上傳到 Github 。SuperTest
demo 項目裏面的路徑 首頁 —— 點擊下方的 RXJAVA按鈕 —— 點擊懸浮效果按鈕 。
可以搜下面代碼
case R.id.collapsing:
intent2Activity(CollapsingActivity.class);
break;
PS:SuperTest 是一個很大的 demo 項目 。SuperTest 項目使用框架是 Supermax (可以 Look Look )。
PS:如果有什麼問題,歡迎文章下面補充 。
微信公衆號:SuperMaxs
如果感覺文章對您有幫助 ,可以關注我的公衆號 SuperMaxs (如果有技術問題可以通過公衆號加私人微信)。
星球瞭解:https://t.zsxq.com/yJ2fq3z