Flutter中如何访问Future函数内的变量值在Widget中生成列表
核心问题排查
- 未定义与JSON结构匹配的数据模型,解析后的原始JSON数据无法直接在UI层使用
loadBreakfast方法中解析得到的items是局部变量,且方法最终返回了空列表,FutureBuilder无法拿到有效数据List.generate的长度参数写法错误,作用域内不存在index变量,且未做判空处理- 未处理Future的加载、异常状态,直接强制拆包容易触发空异常
解决方案
步骤1:创建数据模型
注意不要和你现有的Breakfast Widget重名,单独定义JSON对应的实体类:
class BreakfastItem { final int id; final String rating; final List<String> images; final String title; final String description; final bool isFavorite; final bool isPopular; final int serving; BreakfastItem({ required this.id, required this.rating, required this.images, required this.title, required this.description, required this.isFavorite, required this.isPopular, required this.serving, }); // JSON转模型方法 factory BreakfastItem.fromJson(Map<String, dynamic> json) { return BreakfastItem( id: json['id'], rating: json['rating'], images: List<String>.from(json['images']), title: json['title'], description: json['description'], isFavorite: json['isFavorite'], isPopular: json['isPopular'], serving: json['serving'], ); } }
步骤2:修正Widget代码
import 'package:flutter/services.dart'; import 'dart:convert'; class Breakfast extends StatefulWidget { const Breakfast({ Key? key, }) : super(key: key); @override _BreakfastState createState() => _BreakfastState(); } class _BreakfastState extends State<Breakfast> { Future<String> _loadBreakfastAsset() async { return await rootBundle.loadString('assets/breakfast.json'); } // 修正返回值为解析后的模型数组 Future<List<BreakfastItem>> loadBreakfast() async { String jsonString = await _loadBreakfastAsset(); Map<String, dynamic> map = json.decode(jsonString); List<dynamic> rawItems = map["items"]; // 把原始JSON数组转成模型数组返回给FutureBuilder return rawItems.map((item) => BreakfastItem.fromJson(item)).toList(); } @override Widget build(BuildContext context) { return FutureBuilder<List<BreakfastItem>>( future: loadBreakfast(), builder: (context, AsyncSnapshot<List<BreakfastItem>> snapshot) { // 处理加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 处理加载错误状态 if (snapshot.hasError) { return Center(child: Text('加载失败:${snapshot.error}')); } // 拿到有效数据后渲染UI final List<BreakfastItem> items = snapshot.data ?? []; return Column( children: [ Padding( padding: EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)), child: SectionTitle(title: "Choices", press: () {}), ), SizedBox(height: getProportionateScreenWidth(20)), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ ...List.generate( items.length, (index) { if (items[index].isPopular) { return BreakfastCard(breakfast: items[index]); } return const SizedBox.shrink(); }, ), SizedBox(width: getProportionateScreenWidth(20)), ], ), ) ], ); }, ); } }
注意事项
- 确保你在
pubspec.yaml中已经正确声明了assets/breakfast.json资源 - 你的
BreakfastCard组件接收的参数类型要调整为BreakfastItem,和模型对应
内容的提问来源于stack exchange,提问作者Gheh
相关产品推荐
相关产品推荐

