AppBarLayout是一個垂直的LinearLayout,實現了很多和協調布局一起合作的滾動屬性。其子View可以通過setScrollFlags()或在xml布局中通過app:layout_scrollFlags屬性設置想要的滾動行為。
AppBarLayout很多行為依賴於CoordinatorLayout。如果你使用別的ViewGroup裝AppBarLyout,很多功能就沒有了。
AppBarLayout不能滾動,但是要有一個可以滾動的兄弟View。兄弟View需要設置AppBarLayout.ScrollingViewBehavior。
AppBarLayout是什么,效果是怎樣的
使用AndroidStudio建立一個ScrollActivity,模板就是使用的AppBarLayout,不過例子里還使用了CollapsingToolbarLayout,暫時先不考慮這個,因此對例子做了點修改,xml布局如下:
<?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=".ScrollingActivity2"> <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="@dimen/app_bar_height" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar app:title="AppBarLayout學習" android:id="@+id/toolBar" android:layout_width="match_parent" android:layout_height="@android:dimen/app_icon_size"></android.support.v7.widget.Toolbar>l <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/> </android.support.design.widget.AppBarLayout> <android.support.v4.widget.NestedScrollView android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_scrolling2"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/text_margin" android:text="@string/large_text"/> </android.support.v4.widget.NestedScrollView> </android.support.design.widget.CoordinatorLayout>
父布局是CoordinatorLayout,然后主要兩個布局:AppBarLayout以及NestedScrollView,NestedScrollView設置了layout_behavior屬性,這樣AppBarLayout里面的布局就可以跟着一起滾動,不過由於這里還沒給AppBarLayout里面的scrollFlags設置參數,目前運行效果如下:
可以看到下面的布局滾動,上面的AppBarLayout不為所動。下面就開始為View設置不同屬性,看看效果。
scrollFlags的效果
scrollFlags一共有五個值,一些值是可以組合作用在View上的。五個值分別是:
- scroll:子View隨ScrollView一起滾動
- enterAlways:只要ScrollView向下移動,子View立即響應滾動
- enterAlwaysCollapsed:當ScrollView滾動最頂層時,子View響應滾動事件,直至子View完全顯示
- exitUtilCollapsed:只要ScrollView向上滾動,子View立即響應滾動,直到達到最小高度
- snap:當Scrollview滾動到最頂層時,子View響應滾動事件。松開手指時,依據AppBarLayout移出屏幕區域與生育可視區域對比,自動移向占比大的區域。
scroll
修改AppBarLayout的子View的屬性如下:
<android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:layout_width="match_parent" android:layout_height="@dimen/app_bar_height" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar app:layout_scrollFlags="scroll" app:title="AppBarLayout學習" android:id="@+id/toolBar" android:layout_width="match_parent" android:layout_height="@android:dimen/app_icon_size"></android.support.v7.widget.Toolbar>l <ImageView app:layout_scrollFlags="scroll" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/> </android.support.design.widget.AppBarLayout>
運行效果如下:
可以看到ToolBar和ImageView就好像是ScrollView里的內容一樣,跟着上下滾動;不過需要注意的是,如果單獨設置ImageView的為scroll,而不設置ToolBar,是沒有效果的,因為ToolBar把ImageView給頂住了,只有下面的ScrollView會滾動。
scroll屬性是其他屬性的基礎,並且由於AppBarLayout是一個垂直的LinearLayout,因此一旦一個View沒有設置該屬性,那么該View之后的效果都會生效,可以簡單認為是該View把后面View的滾動效果給頂住了。
enterAlways
在上面例子的基礎上,設置ImageView的scrollFlags="scroll|enterAlways",如下:
<ImageView app:layout_scrollFlags="scroll|enterAlways" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/>
此時滾動效果如下所示:
此時可以看到,向上滾動,沒有區別;向下滾動時,由於ImageView設置了enterAlways,因此首先滾動,直至出現了,然后ScrollView滾動,最后才是ToolBar顯示。
可以理解為設置了enterAlways屬性的View在向下滾動時的優先級高於ScrollView本身,可以實現分段滾動的效果。
enterAlwaysCollapsed
enterAlwaysCollapsed是進一步修飾enterAlways屬性的,上面的例子看到設置了enterAlways后,向下滾動時,ImageView首先滾動,然后才是ScrollView滾動,而設置了enterAlwaysCollapsed之后,再配合minHeight屬性,可以有不同的效果,先看xml設置:
<ImageView android:minHeight="60dp" app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/>
效果如下圖:
可以看到設置了minHeight以及enterAlwaysCollapsed后,ImageView先滾動到最小高度,然后ScrollView滾動,最后ImageView和ToolBar一起滾動。
exitUtilCollapsed
當向上滑動時,稱為exit;向下滑動時,稱為enter,這樣理解起enterAlways和enterAlwaysCollpased就很好理解了,理解exitUtilCollapsed也好理解了。
exitUtilCollapsed用於設置向上滾動時的最小高度,吸頂的功能。舉個例子:
<ImageView android:minHeight="60dp" app:layout_scrollFlags="scroll|exitUntilCollapsed" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/>
效果如下:
可以看到,一開始跟着ScrollView一起向上滾動,當到達最小高度后,就不再滾動,吸頂了。 向下滾動時,當ScrollView滾動頂部了,才繼續滾動了。
snap
snap是一個根據View在屏幕上顯示范圍進行調整的一個屬性,看下效果其實就明白是怎么回事了。
<ImageView android:minHeight="60dp" app:layout_scrollFlags="scroll|snap" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="fitXY" android:src="@drawable/pic_11"/>
效果如下圖:
snap屬性會根據View的顯示范圍,判定是顯示還是隱藏。
監聽AppBarLayout滾動
可以通過設置監聽器來監聽AppBarLayout的移動,比如說隨着滾動,更改AppBarLayout的透明度,代碼如下:
app_bar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, offset -> val toolBarHeight = toolBar.height if (Math.abs(offset) <= toolBarHeight) { appBarLayout.alpha = 1.0f - Math.abs(offset) * 1.0f / toolBarHeight } })
運行效果如下:
當向上滑時,offset的變化是0-->負數;向下滑時,負數--->0。
總結
AppBarLayout是一個垂直的LinearLayout,內部可以布局多個View,在CoordinatorLayout內部與ScrollView共同作用,一共有五種scrollFlags設置,scroll是其他屬性的基礎。
后面會繼續學習與CollapsingToolbarLayout一起的使用。
作者:星風雪雨
鏈接:https://www.jianshu.com/p/bf99260e6b2b
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
