0%

[MaterialDesign] Android AppBarLayout

Introduction

AppBarLayout顧名思義,就是設計在導航欄(Toolbar)頂部頁籤欄(TabLayout)一起使用,來達成一些Material Design風格的一些滑動交互效果。

AppBarLayout本質上是一個垂直的LinearLayout,不過為了實現滑動交互的效果,因此嚴重依賴於CoordinatorLayout,如果在別的ViewGroup裡,則無法發揮AppBarLayout大部分的功能。

AppBarLayout同時要求Child明確的設置各自的AppBarLayout.ScrollingViewBehavior,在代碼中可以使用setScrollFlags(int)方法,在佈局中可以使用app:layout_scrollFlags屬性。

設定scrollFlags,必須使用AppBarLayout.LayoutParams中已經定義好的五個常量:
SCROLL_FLAG_SCROLL
SCROLL_FLAG_ENTER_ALWAYS
SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED
SCROLL_FLAG_EXIT_UNTIL_COLLAPSED
SCROLL_FLAG_SNAP

接下來我們將一一介紹這些flag的不同

scroll

Child View跟滾動事件有直接的關係,也就是說只要手指一滑動,AppBar必定會隨著滑動往上推,或滑動到頂部顯示,這邊有兩點要注意一下。

第一點:如果設置其他的Flag,必須伴隨著使用SCROLL_FLAG_SCROLL才有作用。
第二點:在AppBarLayout裡這個Child View,前面沒有任何Child View設置這個值,那麼這個Child View設置將失去任何作用

第一點稍後做說明,第二點的意思如下圖所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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"
tools:context="net.nickchen45.appbardemo.MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/appbar_id">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_view"
android:textSize="22sp"
android:textColor="@android:color/white"
android:gravity="center"
app:layout_scrollFlags="scroll"/>

<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar_id"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />

</android.support.design.widget.AppBarLayout>

...

</android.support.design.widget.CoordinatorLayout>

大家可以看到AppBarLayout裡,有兩個Child View,第二個**Child View(Toolbar),前面有一個Child View(TextView),且設置著app:layout_scrollFlags=”scroll”**。
運行效果如下:

如果把第一個Child View(TextView)Flag移除,並在第二個Child View(Toolbar)中設置,由於第一個Child View沒有設置任何Flag,所以第二個Child View(TextView)即使設置Flag也沒有效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.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"
tools:context="net.nickchen45.appbardemo.MainActivity">

<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/appbar_id">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/child_view"
android:textSize="22sp"
android:textColor="@android:color/white"
android:gravity="center"/>

<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:id="@+id/toolbar_id"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll"/>

</android.support.design.widget.AppBarLayout>

...

</android.support.design.widget.CoordinatorLayout>

運行效果如下:

enterAlways

app:layout_scrollFlags設置此屬性,與前者scroll對比,前者是先滾動 Scrolling View,後者是先滾動 Child View,當優先滾動的一方全部顯示後,另一方才會開始滾動

AppBarLayoutChild View中設置屬性,前面有說明,除了scroll之外其他的Flag,都需搭配scroll使用

1
app:layout_scrollFlags="scroll|enterAlways"

運行效果如下:

enterAlwaysCollapsed

enterAlways的附加flag,向下滾動時,先會顯示Child View的最小高度,等待ScrollView滑至頂部時,Child View再向下滾動,直到完全顯示

需要定義高度、最小高度、Flag等屬性

1
2
3
android:layout_height="200dp"
android:minHeight="56dp"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"

運行效果如下:

exitUntilCollapsed

當發生向上滾動事件時,Child View會退出螢幕外至保留最小高度,向下滑動到頂部時,Child View才會向下滾動,直到完全顯示

1
2
3
android:layout_height="200dp"
android:minHeight="56dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed"

運行效果如下:

snap

snap簡單理解,就是child view有一個滾動的吸附效果,當child view滾動達到一定比例,即使手指放開,也會自動滾動到全部顯示,反之則會退出螢幕

1
2
android:layout_height="200dp"
app:layout_scrollFlags="scroll|snap"

運行效果如下:

參考資料:
AppBarLayout
AppBarLayout.LayoutParams