Flutter运行报List<dynamic>不是Map<String,dynamic>子类型错误如何解决
错误原因
你的代码存在3处类型不匹配问题,直接触发了类型转换报错:
- 本地JSON的根节点是
Map<String, dynamic>类型,但你在parseRestaurant方法中直接将jsonDecode的返回值强转为List,类型不匹配 - JSON中根节点下的
restaurants是数组类型,但你在RestaurantDetail类中将该字段定义为单个Restaurant对象 - JSON中
menus下的foods、drinks都是数组类型,但你在Menus类中将两个字段分别定义为单个Foods、Drinks对象
修复后的代码
模型类代码
import 'dart:convert'; class RestaurantResponse { late List<Restaurant> restaurants; RestaurantResponse({required this.restaurants}); RestaurantResponse.fromJson(Map<String, dynamic> json) { // 处理restaurants数组 var restaurantsList = json['restaurants'] as List; restaurants = restaurantsList.map((item) => Restaurant.fromJson(item)).toList(); } } class Restaurant { late String id; late String name; late String description; late String pictureId; late String city; late double rating; late Menus menus; Restaurant({ required this.id, required this.name, required this.description, required this.pictureId, required this.city, required this.rating, required this.menus, }); Restaurant.fromJson(Map<String, dynamic> json) { id = json['id']; name = json['name']; description = json['description']; pictureId = json['pictureId']; city = json['city']; rating = json['rating']?.toDouble() ?? 0.0; // 兼容int类型的评分 menus = Menus.fromJson(json['menus']); } } class Menus { late List<Food> foods; late List<Drink> drinks; Menus({ required this.foods, required this.drinks, }); Menus.fromJson(Map<String, dynamic> json) { // 处理食物数组 var foodsList = json['foods'] as List; foods = foodsList.map((item) => Food.fromJson(item)).toList(); // 处理饮品数组 var drinksList = json['drinks'] as List; drinks = drinksList.map((item) => Drink.fromJson(item)).toList(); } } class Food { late String name; Food({required this.name}); Food.fromJson(Map<String, dynamic> json) { name = json['name']; } } class Drink { late String name; Drink({required this.name}); Drink.fromJson(Map<String, dynamic> json) { name = json['name']; } } // 修正解析方法 List<Restaurant> parseRestaurant(String? json) { if (json == null) { return []; } final Map<String, dynamic> rootJson = jsonDecode(json); final response = RestaurantResponse.fromJson(rootJson); return response.restaurants; }
首页代码
补充了FutureBuilder的加载、错误状态兼容,以及图片加载失败的兜底处理:
import 'package:flutter/material.dart'; import 'package:restaurant/data/restaurant.dart'; import 'package:restaurant/style/theme.dart'; class HomePage extends StatelessWidget { static const routeName = '/article_list'; @override Widget build(BuildContext context) { return Scaffold( backgroundColor: kBackgroundColor, body: FutureBuilder<String>( future: DefaultAssetBundle.of(context) .loadString('assets/local_restaurant.json'), builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 加载错误状态 if (snapshot.hasError) { return Center(child: Text('加载失败:${snapshot.error}')); } final List<Restaurant> restaurants = parseRestaurant(snapshot.data); return ListView.builder( itemCount: restaurants.length, itemBuilder: (context, index) { return _buildRestaurantItem(context, restaurants[index]); }, ); }, ), ); } Widget _buildRestaurantItem(BuildContext context, Restaurant restaurant) { return ListTile( contentPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), leading: Image.network( restaurant.pictureId, width: 100, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return const Icon(Icons.broken_image, size: 100); }, ), title: Text(restaurant.name), subtitle: Text(restaurant.city), trailing: Text('⭐ ${restaurant.rating}'), onTap: () {}, ); } }
内容的提问来源于stack exchange,提问作者muhammad alam nur haris
相关产品推荐
相关产品推荐

