You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter:如何将二维菜谱列表指定字段传入ListView.builder

解决方案

1. 优化数据结构与获取逻辑

你当前的recipes是二维列表(每个元素是包含单个菜谱Map的列表),会增加取值复杂度。建议改为一维Map列表,同时修正getUserData的处理逻辑:

// 替换原二维列表为一维Map列表
List<Map<String, dynamic>> recipes = [];

Future<void> getUserData() async {
  int col = (await RecipeModel().getRecipeCount()) - 1;
  int recipeID = 101;
  recipes.clear(); // 清空旧数据,避免重复加载
  for (int i = 0; i < col; i++, recipeID++) {
    // 获取单条菜谱数据,返回的是包含单个Map的列表,取第一个元素
    final dynamic result = await RecipeModel().getRecipeData(recipeID.toString());
    if (result is List && result.isNotEmpty) {
      recipes.add(result.first as Map<String, dynamic>);
    }
  }
  setState(() {}); // 更新UI
}

2. 用FutureBuilder处理异步加载

因为getUserData是异步操作,直接渲染ListView会出现数据未就绪的问题,用FutureBuilder管理异步状态:

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: FutureBuilder(
      future: getUserData(),
      builder: (context, snapshot) {
        // 数据加载中
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }
        // 加载完成渲染列表
        return ListView.builder(
          padding: const EdgeInsets.only(top: 0),
          itemCount: recipes.length,
          itemBuilder: (context, index) {
            final recipe = recipes[index];
            return RecipeCard(
              isAdmin: true,
              title: recipe['recipeName'] ?? 'Unknown',
              cookTime: recipe['recipeTime'] ?? 'Unknown',
              rating: recipe['recipeRating'].toString(),
              thumbnailUrl: recipe['recipeURL'] ?? '',
            );
          },
        );
      },
    ),
  );
}

3. 可选:定义Recipe模型类(更规范)

为避免直接用Map取值的松散性,可定义模型类让数据结构更清晰:

class Recipe {
  final String name;
  final String description;
  final String cookTime;
  final List<String> ingredients;
  final double rating;
  final String imageUrl;

  Recipe({
    required this.name,
    required this.description,
    required this.cookTime,
    required this.ingredients,
    required this.rating,
    required this.imageUrl,
  });

  // 从Map转Recipe对象
  factory Recipe.fromMap(Map<String, dynamic> map) {
    return Recipe(
      name: map['recipeName'] ?? 'Unknown',
      description: map['recipeDescription'] ?? '',
      cookTime: map['recipeTime'] ?? 'Unknown',
      ingredients: List<String>.from(map['recipeIngrediants'] ?? []),
      rating: (map['recipeRating'] as num).toDouble(),
      imageUrl: map['recipeURL'] ?? '',
    );
  }
}

修改数据存储和获取逻辑:

List<Recipe> recipes = [];

Future<void> getUserData() async {
  int col = (await RecipeModel().getRecipeCount()) - 1;
  int recipeID = 101;
  recipes.clear();
  for (int i = 0; i < col; i++, recipeID++) {
    final dynamic result = await RecipeModel().getRecipeData(recipeID.toString());
    if (result is List && result.isNotEmpty) {
      recipes.add(Recipe.fromMap(result.first as Map<String, dynamic>));
    }
  }
  setState(() {});
}

对应的ListView写法:

itemBuilder: (context, index) {
  final recipe = recipes[index];
  return RecipeCard(
    isAdmin: true,
    title: recipe.name,
    cookTime: recipe.cookTime,
    rating: recipe.rating.toString(),
    thumbnailUrl: recipe.imageUrl,
  );
},

内容的提问来源于stack exchange,提问作者Mr Fin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 18:40:32