Flutter中如何条件使用slim_model配合FutureBuilder预加载展示部分数据
实现方案
1. 修改FullView组件入参,新增可选精简数据参数
在FullView的构造函数中增加非必填的精简数据参数,深度链接场景下无需传入该参数即可正常兼容:
class FullView extends StatefulWidget { final String id; // 可选参数,持有跳转时传入的精简数据,无数据时为null final SlimDataModel? slimData; const FullView({ Key? key, required this.id, this.slimData, }) : super(key: key); @override _FullViewState createState() => _FullViewState(); }
*如果没有单独定义SlimDataModel类,也可以拆分为String? initialTitle、String? initialImage两个独立可选参数,使用逻辑一致。
2. 调整State状态管理逻辑
不再完全依赖FutureBuilder做状态控制,改为在State中自行管理加载状态、全量数据、错误信息,同时兼容两种加载场景:
class _FullViewState extends State<FullView> { FullDataModel? _fullData; bool _isLoading = true; String? _errorMsg; @override void initState() { super.initState(); _loadFullData(); } Future<void> _loadFullData() async { try { final result = await Repository().getModel(widget.id); if (mounted) { setState(() { _fullData = result; _isLoading = false; }); } } catch (e) { if (mounted) { setState(() { _errorMsg = 'Something went wrong, we are working on fixing it!'; _isLoading = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( body: _buildBody(), ); } Widget _buildBody() { // 错误场景优先展示错误提示 if (_errorMsg != null) { return Center(child: Text(_errorMsg!)); } // 全量数据加载完成直接渲染完整页面 if (_fullData != null) { return _body(_fullData!, context); } // 加载中场景分层处理 if (_isLoading) { // 有传入精简数据,优先展示已有title和image,剩余内容展示加载占位 if (widget.slimData != null) { final slim = widget.slimData!; return Column( children: [ Image.network(slim.image), Text(slim.title), const Expanded( child: Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>(ColorConstants.accent1), ), ), ) ], ); } // 无精简数据(如深度链接场景),展示全页加载动画 else { return const Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation<Color>(ColorConstants.accent1), ), ); } } // 兜底异常展示 return const Center(child: Text('Something went wrong, we are working on fixing it!')); } }
3. 修改跳转逻辑,传入已有的精简数据
跳转时把已有的slimData传入FullView即可:
Navigator.push( context, MaterialPageRoute( builder: (context) { return FullView( id: slimData.id, slimData: slimData, ); }, fullscreenDialog: true, ), );
内容的提问来源于stack exchange,提问作者Nithin Sai
相关产品推荐
相关产品推荐

