本文多圖預警,請注意在wifi下觀看O(∩_∩)O~~
不少軟件都有吸附頂部的效果,一圖勝千言(這裏偷懶,使用的是簡書中的圖)。 android
官方文檔是這樣解釋的。一個使用slivers
來建立自定義滾動效果的ScrollView
。
CustomScrollView
讓你直接提供 slivers
來建立不一樣的滾動效果,好比lists,grids 以及 expanding headers。
若是要建立一個包含 可伸展的appbar ,後面跟着list 和grid 這樣的滾動視圖,可使用這三種slivers:SliverAppBar
,SliverAppBar
和SliverGrid
。
在這些slivers
中的widget必須產生 RenderSliver
對象。
爲了控制這些滾動視圖的初始滾動偏移量,能夠經過 controller
和他的 ScrollController.initialScrollOffset
屬性來設置。git
下面的例子展現了 scroll view包含 flexible pinned app bar, 一個grid 和一個無限的list。github
class CustomWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 150.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () {
/* ... */
},
),
]),
SliverGrid(
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,
mainAxisSpacing: 10.0,
crossAxisSpacing: 10.0,
childAspectRatio: 4.0,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.teal[100 * (index % 9)],
child: Text('grid item $index'),
);
},
childCount: 20,
),
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100 * (index % 9)],
child: Text('list item $index'),
);
},
),
),
],
);
}
}
複製代碼
效果圖見下方SliverAppBar
的圖,兩個合在一塊兒展現了。bash
定義: 配套 CustomScrollView
使用的material design app bar。
一個app bar由 一個 toolbar 和 其餘潛在的widgets組成,好比 TabBar
和 FlexibleSpaceBar
。 App bars 一般會 經過IconButton
s來暴露一個或者多個common actions,後面也可選的跟PopupMenuButton
,能夠作一些經常使用操做。
Sliver app bars 一般被用做 CustomScrollView
的第一個孩子,能夠根據scroll view中其餘孩子的滾動偏移量來動態調整高度。 若是要使用一個固定高度的app bar 能夠看AppBar
, 用在Scaffold.appBar
這一塊。
這個AppBar展現一些toolbar widgets,leading
(最左側的按鈕)、title
以及actions
,都在bottom
之上。若是flexibleSpace
widget也被指定內容了,它將會被放在 toolbar 和 bottom widget 之下。
下面這段代碼能夠被CustomScrollView
的[CustomScrollView.slivers]使用:app
SliverAppBar(
expandedHeight: 150.0,
flexibleSpace: const FlexibleSpaceBar(
title: Text('Available seats'),
),
actions: <Widget>[
IconButton(
icon: const Icon(Icons.add_circle),
tooltip: 'Add new entry',
onPressed: () { /* ... */ },
),
]
)
複製代碼
將這段代碼放入到上面CustomScrollView的樣例代碼中,效果以下:
less
下面的內容主要是細緻分析 SliverAppBar
構造函數中 floating
、snap
、pinned
取不一樣的值對於交互效果的影響變化。ide
App bar -- [floating]: false, [pinned]: false, [snap]: false:
函數
App bar -- [floating]: true, [pinned]: false, [snap]: false:
flex
App bar -- [floating]: true, [pinned]: false, [snap]: true:
動畫
App bar -- [floating]: true, [pinned]: true, [snap]: false:
App bar -- [floating]: true, [pinned]: true, [snap]: true:
App bar with [floating]: false, [pinned]: true, [snap]: false:
snap
屬性只能在float
屬性爲true的狀況下設置.
總結下來
pinned
最容易理解,是否固定appbar不滑出屏幕。
floating
改變了下滑時候appbar出現優先級的順序,appbar(以及延伸區域)出現的優先級>list的優先級。
snap
要結合floating
,檢測到下滑的輕微加速度就會以動畫形式將appbar徹底展開蓋在list之上。
這裏留意到一個現象是在慢速持續的向下滑動時,snap
的值true和false差異不大。
本文樣例分支代碼已上傳github ,分支CustomScrollView分支。
若是你以爲這篇文章對你有益,還請幫忙轉發和點贊,萬分感謝。