如何在 Flutter 中制作多级可靠的下拉列表?

Mue*_*ema 3 dart flutter dropdownbutton

我一直致力于提供两个下拉按钮,以便用户轻松选择汽车型号及其各自的品牌。下面是我拥有的静态列表的代码片段。任何反馈都将受到高度赞赏。

final List<String> carModel = [
    'Audi',
    'BMW',
    'Chevrolet',
    'Chrysler',
    'Daihatsu',
    'Ford',
    'Hino',
    'Honda',
    'Isuzu',
    'Jaguar',
    'Jeep',
    'Landrover',
    'Lexus',
    'Mazda',
    'Mercedes',
    'Mitsubishi',
    'Nissan',
    'Peugeot',
    'Porsche',
    'Subaru',
    'Suzuki',
    'Toyota',
    'UD',
    'Volkswagen',
    'Volvo'
  ];
  final List<String> audiMake = [
    'A3',
    'A4',
    'A5',
    'A6',
    'A7',
    'A8',
    'Q3',
    'Q5',
    'Q7',
    'Q8',
    'R8',
    'TT',
  ];
  final List<String> bmwMake = [
    '1 Series',
    '2 Series',
    '3 Series',
    '4 Series',
    '5 Series',
    '6 Series',
    '7 Series',
    '8 Series',
    'M2',
    'M3',
    'M4',
    'M5',
    'M6',
    'X1',
    'X2',
    'X3',
    'X4',
    'X5',
    'X6',
    'X7',
    'Z4',
    'i3',
    'i8',
  ];
Run Code Online (Sandbox Code Playgroud)

这是我一直在使下拉按钮的功能发挥作用的代码:

 DropdownButton<String>(
                value: selectedCarModel,
                items: carModel.map((e) {
                  return DropdownMenuItem<String>(
                    value: e,
                    child: Text('$e'),
                  );
                }).toList(),
                onChanged: (val) {
                  setState(() {
                    selectedCarModel = val!;
                  });
                }),
            const SizedBox(
              height: 10,
            ),
            DropdownButton<String>(
                value: selectedCarMake,
                items: carMake.map((e) {
                  return DropdownMenuItem<String>(
                    value: e,
                    child: Text('$e'),
                  );
                }).toList(),
                onChanged: (val) {

                  carMake = val == 'Audi' ? audiMake : bmwMake;
                  setState(() {
                    selectedCarMake = val!;
                  });
                }),
Run Code Online (Sandbox Code Playgroud)

Md.*_*ikh 5

使用多下拉按钮的概念将是第二个下拉列表始终取决于第一个下拉值。有必要使下拉按钮可为空。因此,如果第一个下拉按钮发生变化,第二个下拉按钮必须为空,否则如果第一个下拉按钮选择了某些内容而第二个下拉按钮不包含该值,它将提供基于错误的信息。好的代码比我的解释效果更好。

让我们使用 Map 来简化该过程。

class MultiLevelDropDownExample extends StatefulWidget {
  const MultiLevelDropDownExample({Key? key}) : super(key: key);

  @override
  State<MultiLevelDropDownExample> createState() =>
      _MultiLevelDropDownExampleState();
}

class _MultiLevelDropDownExampleState extends State<MultiLevelDropDownExample> {
  final List<String> audiMake = [
    'A3',
    'A4',
  ];
  final List<String> bmwMake = [
    '1 Series',
    '2 Series',
  ];

  String? selectedCardModel;
  String? selectedMake;

  late Map<String, List<String>> dataset = {
    'Audi': audiMake,
    'BMW': bmwMake,
  };

  onCarModelChanged(String? value) {
    //dont change second dropdown if 1st item didnt change
    if (value != selectedCardModel) selectedMake = null;
    setState(() {
      selectedCardModel = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          DropdownButton<String?>(
              value: selectedCardModel,
              items: dataset.keys.map((e) {
                return DropdownMenuItem<String?>(
                  value: e,
                  child: Text('$e'),
                );
              }).toList(),
              onChanged: onCarModelChanged),
          const SizedBox(
            height: 10,
          ),
          DropdownButton<String?>(
              value: selectedMake,
              items: (dataset[selectedCardModel] ?? []).map((e) {
                return DropdownMenuItem<String?>(
                  value: e,
                  child: Text('$e'),
                );
              }).toList(),
              onChanged: (val) {
                setState(() {
                  selectedMake = val!;
                });
              }),
          //
        ],
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)