Flutter中如何在SliverAppBar下固定Body内的指定Widget?
解决方案
你的问题出在把需要固定的Widget放在了NestedScrollView的body里——body属于可滚动区域的一部分,所以会跟着列表一起滚动。要让它和SliverAppBar一起固定,得把它移到Sliver头部区域里。
下面给两种可行的实现方式:
方式一:修改NestedScrollView的头部构造器
直接在headerSliverBuilder里添加固定Widget对应的Sliver组件,让它和SliverAppBar一起成为固定头部:
Scaffold( body: NestedScrollView( headerSliverBuilder: (context, innerBoxIsScrolled) => [ SliverAppBar( leading: InkWell( onTap: () => Navigator.of(context).pop(), child: const Icon(Icons.arrow_back_ios_new), ), expandedHeight: 300, flexibleSpace: const FlexibleSpaceBar( title: Text('All Transactions'), ), pinned: true, floating: true, ), // 把需要固定的Widget用SliverToBoxAdapter包裹,加入头部Sliver列表 const SliverToBoxAdapter( child: Padding( padding: EdgeInsets.all(8.0), child: SizedBox( height: 50, color: Colors.grey, child: Center(child: Text('Pinned Widget')), ), ), ), ], // body直接放列表即可,不需要再包裹Column body: showListView(), ), )
方式二:使用CustomScrollView直接组合Sliver组件
如果不需要NestedScrollView的嵌套滚动特性,用CustomScrollView更直接,把所有固定和滚动的Sliver组件按顺序组合:
Scaffold( body: CustomScrollView( slivers: [ SliverAppBar( leading: InkWell( onTap: () => Navigator.of(context).pop(), child: const Icon(Icons.arrow_back_ios_new), ), expandedHeight: 300, flexibleSpace: const FlexibleSpaceBar( title: Text('All Transactions'), ), pinned: true, floating: true, ), const SliverToBoxAdapter( child: Padding( padding: EdgeInsets.all(8.0), child: SizedBox( height: 50, color: Colors.grey, child: Center(child: Text('Pinned Widget')), ), ), ), // 把ListView转成SliverList SliverList( delegate: SliverChildBuilderDelegate( (context, index) => showListView().children[index], childCount: showListView().children.length, ), ), ], ), )
两种方式都能实现:向上滚动时SliverAppBar先收缩到固定高度,之后和下方的固定Widget一起保持不动,只有下面的列表内容滚动。
内容的提问来源于stack exchange,提问作者user22362195
相关产品推荐
相关产品推荐

