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:展開區域的高度。
flexibleSpace:展開取消顯示內容。
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:顯示內容。
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組件可以將多個組件組合在一起,具有統一的滾動效果,但是CustomScrollView隻能嵌套Sliver系列的組件,如SliverList、SliverGrid、SliverPadding、SliverAppBar等。
NestedScrollView可以協調兩個滾動組件滑動。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)], ), )
優化聯動效果
SliverAppBar+CustomScrollView組合,當反向滑動時,SliverAppBar就會整體回到屏幕頂部,出現遮擋問題,為瞭解決該問題,可以用在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(), ), ); } }
到此這篇關於Flutter Sliver滾動組件的文章就介紹到這瞭,更多相關Flutter 滾動組件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 浮動AppBar中的textField焦點回滾問題解決
- Flutter之 ListView組件使用示例詳解
- 在Flutter中制作翻轉卡片動畫的完整實例代碼
- Flutter 如何設置App的主色調與字體
- Android Flutter實現自定義下拉刷新組件