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

Flutter/Dart中如何将指定JSON解析为类对象并用于多级下拉菜单

Flutter/Dart 多级下拉菜单实现方案

第一步:JSON转Dart模型类

首先将目标JSON结构映射为可复用的Dart类,同时编写解析方法:

// 车型模型类
class CarModel {
  final String model;
  final int doors;

  CarModel({required this.model, required this.doors});

  factory CarModel.fromJson(Map<String, dynamic> json) {
    return CarModel(
      model: json['model'],
      doors: json['doors'],
    );
  }
}

// JSON解析方法,返回格式为「品牌名: 对应车型列表」的映射
Map<String, List<CarModel>> parseCarJson(Map<String, dynamic> json) {
  final carsJson = json['cars'] as Map<String, dynamic>;
  Map<String, List<CarModel>> result = {};
  carsJson.forEach((brand, modelsList) {
    List<CarModel> models = (modelsList as List).map((e) => CarModel.fromJson(e)).toList();
    result[brand] = models;
  });
  return result;
}

第二步:多级下拉完整实现

二级下拉逻辑为:第一级选汽车品牌,第二级联动展示对应品牌下的车型,未选品牌时车型下拉默认禁用:

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('汽车多级下拉示例')),
        body: const CarDropdownPage(),
      ),
    );
  }
}

class CarDropdownPage extends StatefulWidget {
  const CarDropdownPage({super.key});

  @override
  State<CarDropdownPage> createState() => _CarDropdownPageState();
}

class _CarDropdownPageState extends State<CarDropdownPage> {
  // 解析后的汽车数据源
  Map<String, List<CarModel>> carData = {};
  // 选中状态存储
  String? selectedBrand;
  CarModel? selectedModel;

  @override
  void initState() {
    super.initState();
    // 模拟接口返回的JSON数据,实际使用替换为真实接口返回值即可
    final mockJson = {
      "cars": {
        "Nissan": [
          {"model": "Sentra", "doors":4},
          {"model": "Maxima", "doors":4},
          {"model": "Skyline", "doors":2}
        ],
        "Ford": [
          {"model": "Taurus", "doors":4},
          {"model": "Escort", "doors":4}
        ]
      }
    };
    carData = parseCarJson(mockJson);
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // 第一级:品牌下拉
          const Text('选择品牌:'),
          DropdownButton<String>(
            value: selectedBrand,
            hint: const Text('请选择品牌'),
            isExpanded: true,
            items: carData.keys.map((brand) {
              return DropdownMenuItem(
                value: brand,
                child: Text(brand),
              );
            }).toList(),
            onChanged: (value) {
              setState(() {
                selectedBrand = value;
                // 切换品牌时清空已选车型,避免状态异常
                selectedModel = null;
              });
            },
          ),
          const SizedBox(height: 30),
          // 第二级:车型下拉
          const Text('选择车型:'),
          DropdownButton<CarModel>(
            value: selectedModel,
            hint: selectedBrand == null 
                ? const Text('请先选择品牌') 
                : const Text('请选择车型'),
            isExpanded: true,
            // 未选品牌时设置onChanged为null,直接禁用下拉
            onChanged: selectedBrand == null ? null : (value) {
              setState(() {
                selectedModel = value;
              });
            },
            items: selectedBrand == null 
                ? [] 
                : carData[selectedBrand]!.map((model) {
                    return DropdownMenuItem(
                      value: model,
                      child: Text('${model.model}(${model.doors}门)'),
                    );
                  }).toList(),
          ),
          const SizedBox(height: 30),
          // 选中结果展示
          if (selectedModel != null)
          Text('已选车辆:$selectedBrand ${selectedModel!.model},${selectedModel!.doors}门'),
        ],
      ),
    );
  }
}

核心逻辑说明

  • 品牌下拉选项直接从解析后数据源的key映射生成,不需要额外处理映射关系
  • 车型下拉的选项完全依赖选中的品牌动态生成,状态联动逻辑全部放在setState中处理
  • 每个DropdownMenuItem的value直接绑定对应的数据对象,取值时不需要额外做索引匹配

内容的提问来源于stack exchange,提问作者jagan V026

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 22:45:01