Flutter开发:如何将FutureBuilder整合到现有SliverAppBar代码中
Flutter SliverAppBar 整合 FutureBuilder 方案
核心逻辑
CustomScrollView的slivers参数要求所有子元素为Sliver家族组件,因此FutureBuilder需要包裹在CustomScrollView外层,根据异步请求的不同状态返回对应的Sliver布局即可。
完整实现代码
// 需提前在State类中声明Future并在initState中初始化:late Future<Article> _futureArticle; @override Widget build(BuildContext context) => Scaffold( body: FutureBuilder<Article>( future: _futureArticle, builder: (BuildContext context, AsyncSnapshot<Article> snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return CustomScrollView( slivers: [ _buildCommonSliverAppBar(), const SliverFillRemaining( child: Center(child: CircularProgressIndicator()), ) ], ); } // 加载错误状态 if (snapshot.hasError) { return CustomScrollView( slivers: [ _buildCommonSliverAppBar(), SliverFillRemaining( child: Center(child: Text('加载失败:${snapshot.error}')), ) ], ); } // 数据加载完成状态 if (snapshot.hasData) { final article = snapshot.data?.data; return CustomScrollView( slivers: [ // 可根据需求替换AppBar标题为article中的字段 _buildCommonSliverAppBar(), // 普通Widget需包裹SliverToBoxAdapter才能放入slivers数组 SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.all(16), child: Text(article?.content ?? '暂无内容'), ), ), // 若要渲染长列表可使用SliverList,示例如下: // SliverList.builder( // itemCount: article?.itemList?.length ?? 0, // itemBuilder: (context, index) => ListTile( // title: Text(article.itemList[index].title), // ), // ) ], ); } // 兜底空数据状态 return const Center(child: Text('暂无数据')); }, ), ); // 抽离复用的SliverAppBar,减少重复代码 Widget _buildCommonSliverAppBar() { return SliverAppBar( backgroundColor: Colors.red, expandedHeight: 200, floating: true, pinned: true, flexibleSpace: FlexibleSpaceBar( background: Image.network( 'https://source.unsplash.com/random?monochromatic+dark', fit: BoxFit.cover, ), title: const Text('Flexible Title'), centerTitle: true, ), leading: const Icon(Icons.arrow_back), actions: const [ Icon(Icons.settings), SizedBox(width: 12), ], ); }
注意事项
- 不要在build方法中直接创建
_futureArticle实例,需要在initState中完成初始化,避免页面重绘时重复触发异步请求 - 所有放入
slivers数组的组件必须是Sliver类型,普通组件可包裹SliverToBoxAdapter后使用
内容的提问来源于stack exchange,提问作者gegentierversuche
相关产品推荐
相关产品推荐

