Flutter如何根据Future返回值渲染不同Widget?
问题:根据Future结果在列表卡片中显示不同图标
需求是根据markedFavourites(_id)返回的Future<bool>值,在ListView的每个数据卡片里切换显示实心/空心的收藏图标。尝试过.then和FutureBuilder但未成功,原代码如下:
原Scaffold代码
child: ListView.builder( itemCount: fullList.length, itemBuilder: (BuildContext context, int index) { return dataCard(context, fullList, index); }),
原dataCard代码
Row( children: [ Expanded( flex: 8, child: Text(dl[i].Name, style: TextStyle(color: Colors.blue[400], fontSize: 16)), ), Expanded( flex: 1, child: setFavouriteIcon(dl[i].ID), ), ], ),
原setFavouriteIcon代码
Widget setFavouriteIcon(_id) { final marked = markedFavourites(_id).then((value) { //markedFavourites返回Future<bool> if (value == true) { return Icon( size: 24, Icons.favorite, color: Colors.red, ); } else { return Icon( size: 24, Icons.favorite_border_outlined, color: Colors.red, ); } }); return Text(''); //无此代码会报错:必须返回非空值 }
解决方案
原代码的核心问题是:setFavouriteIcon需要同步返回Widget,但.then是异步操作,你拿到的marked是Future<Widget>,无法直接作为返回值,所以只能返回空Text,异步生成的图标根本没被渲染。
正确的做法是用FutureBuilder处理异步状态,直接在setFavouriteIcon里返回FutureBuilder:
Widget setFavouriteIcon(_id) { return FutureBuilder<bool>( // 传入异步判断方法 future: markedFavourites(_id), // 设置初始状态的默认值(比如默认未收藏) initialData: false, builder: (BuildContext context, AsyncSnapshot<bool> snapshot) { // 处理加载状态(可选,显示占位图标) if (snapshot.connectionState == ConnectionState.waiting) { return Icon(Icons.favorite_border_outlined, size: 24, color: Colors.grey); } // 处理返回结果,空值兜底为false bool isFavourite = snapshot.data ?? false; // 根据结果返回对应图标 return Icon( size: 24, isFavourite ? Icons.favorite : Icons.favorite_border_outlined, color: Colors.red, ); }, ); }
修改后,原有的dataCard和ListView.builder代码不需要改动,直接调用setFavouriteIcon(dl[i].ID)即可。FutureBuilder会自动监听异步请求的状态,在请求完成后自动更新图标。
内容的提问来源于stack exchange,提问作者Tony Lam
相关产品推荐
相关产品推荐

