Flutter Sliver滾動組件的演示代碼
Flutter Sliver滾動組件
SliverList & SliverGrid
需要同時滾動ListView和GridView時可以使用SliverList和SliverGrid。

CustomScrollView(
slivers: [
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return Container(
height: 50,
color: Colors.primaries[index % Colors.primaries.length],
);
},
childCount: 5,
),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: Colors.primaries[index % Colors.primaries.length],
);
},
childCount: 20,
),
),
],
)
SliverAppBar
pinned:是否固定在屏幕頂部。
expandedHeight:展開區(qū)域的高度。
flexibleSpace:展開取消顯示內(nèi)容。

CustomScrollView(
slivers: [
SliverAppBar(
pinned: true,
expandedHeight: 200,
flexibleSpace: FlexibleSpaceBar(
title: const Text("SliverAppBar"),
background: Image.asset("images/avatar.jpg", fit: BoxFit.cover),
),
),
SliverFixedExtentList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
alignment: Alignment.center,
color: Colors.primaries[index % Colors.primaries.length],
child: Text("$index"),
);
},
),
itemExtent: 50.0,
),
],
)
SliverPersistentHeader
SliverPersistentHeader組件可以控制滾動的最大高度和最小高度,類似SliverAppBar效果。
build:顯示內(nèi)容。
maxExtent & minExtent:滾動的高度范圍。
shouldRebuild:是否需要更新。

CustomScrollView(
slivers: [
SliverPersistentHeader(
pinned: true,
delegate: MySliverPersistentHeaderDelegate(),
),
SliverGrid(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5,
mainAxisSpacing: 5,
),
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
color: Colors.primaries[index % Colors.primaries.length],
);
},
),
),
],
)
class MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
@override
Widget build(
BuildContext context, double shrinkOffset, bool overlapsContent) {
return Container(
color: Colors.blue,
alignment: Alignment.center,
child: Text(
"hello world",
style: TextStyle(color: Colors.white),
),
);
}
@override
double get maxExtent => 200;
@override
double get minExtent => 50;
@override
bool shouldRebuild(covariant SliverPersistentHeaderDelegate oldDelegate) {
return false;
}
}
SliverToBoxAdapter
CustomScrollView只能包含Sliver組件,如果需要使用普通組件可以使用SliverToBoxAdapter。

CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
height: 200,
color: Colors.black26,
alignment: Alignment.center,
child: Text("hello world"),
),
),
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return Container(
height: 60,
color: Colors.primaries[index % Colors.primaries.length],
);
},
childCount: 50,
),
),
],
)
CustomScrollView & NestedScrollView
CustomScrollView組件可以將多個組件組合在一起,具有統(tǒng)一的滾動效果,但是CustomScrollView只能嵌套Sliver系列的組件,如SliverList、SliverGrid、SliverPadding、SliverAppBar等。
NestedScrollView可以協(xié)調(diào)兩個滾動組件滑動。NestedScrollView在邏輯上將可滾動組件分為header和body兩部分,heade部分只能接收Sliver類型的組件,而body部分可以接收任意類型的組件。
NestedScrollView+SliverAppBar+SliverFixedExtentList+ListView

NestedScrollView(
//Sliver組件
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
title: const Text("嵌套ListView"),
pinned: true, //固定AppBar
forceElevated: true,
),
SliverFixedExtentList(
itemExtent: 50,
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return ListTile(title: Text("$index"));
},
childCount: 5,
),
),
];
},
//滾動組件
body: ListView.builder(
padding: const EdgeInsets.all(8),
physics: const ClampingScrollPhysics(), //需要
itemCount: 30,
itemBuilder: (BuildContext context, int index) {
return SizedBox(
height: 50,
child: Center(child: Text("item $index")),
);
},
),
)
NestedScrollView+SliverAppBar+CustomScrollView

NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverAppBar(
floating: true,
snap: true,
expandedHeight: 200,
forceElevated: innerBoxIsScrolled,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset(
"images/logo.png",
fit: BoxFit.cover,
),
),
),
];
},
body: CustomScrollView(
slivers: [buildSliverList(50)],
),
)
優(yōu)化聯(lián)動效果
SliverAppBar+CustomScrollView組合,當(dāng)反向滑動時,SliverAppBar就會整體回到屏幕頂部,出現(xiàn)遮擋問題,為了解決該問題,可以用在header里用SliverOverlapAbsorber組件包裹SliverAppBar,body里Sliver列表最前面添加一個SliverOverlapInjector。
NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar(
floating: true,
snap: true,
expandedHeight: 200,
forceElevated: innerBoxIsScrolled,
flexibleSpace: FlexibleSpaceBar(
background: Image.asset(
"images/logo.png",
fit: BoxFit.cover,
),
),
),
),
];
},
body: Builder(
builder: (BuildContext context) {
return CustomScrollView(
slivers: [
SliverOverlapInjector(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
buildSliverList(50),
],
);
},
),
)
NestedScrollView+TabBarView

class MyPageView extends StatefulWidget {
late List<String> tabs;
MyPageView({Key? key, required this.tabs}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _MyPageViewState();
}
}
class _MyPageViewState extends State<MyPageView>
with SingleTickerProviderStateMixin {
late TabController _controller;
@override
void initState() {
super.initState();
_controller = TabController(length: widget.tabs.length, vsync: this);
}
@override
void dispose() {
super.dispose();
_controller.dispose();
}
@override
Widget build(BuildContext context) {
return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return [
SliverOverlapAbsorber(
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
sliver: SliverAppBar(
title: const Text("hi Flutter"),
floating: true,
snap: true,
forceElevated: innerBoxIsScrolled,
bottom: TabBar(
controller: _controller,
tabs: widget.tabs.map((e) => Tab(text: e)).toList(),
),
),
),
];
},
body: TabBarView(
controller: _controller,
children: widget.tabs.map((e) {
return Builder(builder: (BuildContext context) {
return CustomScrollView(
key: PageStorageKey(e),
slivers: [
SliverOverlapInjector(
handle:
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
),
SliverPadding(
padding: const EdgeInsets.all(9),
sliver: buildSliverList(50),
),
],
);
});
}).toList(),
),
);
}
}
到此這篇關(guān)于Flutter Sliver滾動組件的文章就介紹到這了,更多相關(guān)Flutter 滾動組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android使用LinearLayout設(shè)置邊框
這篇文章主要介紹了Android如何使用LinearLayout設(shè)置邊框,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
解決Android Studio 3.0 butterknife:7.0.1配置的問題
下面小編就為大家分享一篇解決Android Studio 3.0 butterknife:7.0.1配置的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
Android實現(xiàn)輸入法彈出時把布局頂上去和登錄按鈕頂上去的解決方法
這篇文章主要介紹了Android實現(xiàn)輸入法彈出時把布局頂上去和登錄按鈕頂上去的解決方法,需要的朋友可以參考下2017-11-11
Android編程之基于Log演示一個activity生命周期實例詳解
這篇文章主要介紹了Android編程之基于Log演示一個activity生命周期,結(jié)合完整實例形式較為詳細的分析總結(jié)了Log演示activity生命周期的具體用法及Log的具體使用方法,需要的朋友可以參考下2015-12-12
Android中TelephonyManager類的方法實例分析
這篇文章主要介紹了Android中TelephonyManager類的方法,以實例形式較為詳細的分析了Android基于TelephonyManager類獲取手機各種常用信息的相關(guān)技巧,需要的朋友可以參考下2015-09-09
Android 照片選擇區(qū)域功能實現(xiàn)示例
這篇文章主要介紹了Android 照片選擇區(qū)域功能實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04

