首页 > 解决方案 > 颤振中的多级下拉按钮 - 我们可以消除 if 语句吗?

问题描述

我实现了两级下拉按钮,其中按钮#2 取决于按钮#1 的选择。第一个下拉列表是国家列表,根据用户选择的国家,第二个下拉列表中将提供城市列表。主要问题是关于两个下拉列表之间的链接,我正在使用一系列 if 语句来告诉代码,如果我选择国家 x,则显示 x 的城市等。在下面的示例代码中,我只包括 6国家,所以写 if 语句仍然干净且易于管理,但是如果国家列表达到 150 个呢?我需要编写 150 行 if 语句来将国家与城市联系起来吗?有没有更聪明的方法来做到这一点?我可以利用国家名称和包含其城市的列表名称的相似之处吗?例如“美国”和“城市美国”

import 'package:flutter/material.dart';
void main() {
  runApp(MyApp());}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
String? dropdownValue;
String? dropdownCity;
List<String> selectedCities=[];
String? selectedCountry;
@override

Widget build(BuildContext context) {
  final List<String> country = ['USA', 'Egypt', 'Spain', 'Mexico', 'Russia', 'China'];
  final List<String> cityEgypt =['Cairo', 'Alexandria'];
  final List<String> cityUSA = ['Houston', 'Dallas'];
  final List<String> citySpain = ['Madrid', 'Barcelona'];
  final List<String> cityMexico = ['Cancun', 'Mexico City'];
  final List<String> cityRussia=['Moscow', 'Saint Petersburg'];
  final List<String> cityChina = ['Gowanzo', 'Beijing'];
  return MaterialApp(
      title: 'Drop down fun',
      home: Scaffold(
      backgroundColor: Colors.greenAccent,
      body:Column(
      children: <Widget>[
      Padding(
      padding: const EdgeInsets.all(8.0),
  child: Text('Please choose your location', style:TextStyle(fontWeight: FontWeight.bold, fontSize: 25)),
  ),

    Padding(
  padding: const EdgeInsets.all(10.0),
  child: DropdownButton<String>(
  value: dropdownValue,
  icon: Icon(Icons.map),
  disabledHint: Text('Choose country first'),

  style:TextStyle(color: Colors.black, fontSize: 15) ,
  onChanged: (String? newValue) {
  setState(() {
  dropdownValue = newValue;
  selectedCountry = dropdownValue;
  dropdownCity = null;
  if(selectedCountry=='Egypt'){selectedCities=cityEgypt;}
  else if(selectedCountry=='USA'){selectedCities=cityUSA;}
  else if(selectedCountry=='Spain'){selectedCities=citySpain;}
  else if(selectedCountry=='Mexico'){selectedCities=cityMexico;}
  else if(selectedCountry=='Russia'){selectedCities=cityRussia;}
  else if(selectedCountry=='China'){selectedCities=cityChina;}
  });
  },
  items: country.map((String item){
  return DropdownMenuItem<String>(
  value: item,
  child: Container(
  color: Colors.greenAccent,
    child: Text(item),
  ),
  );
  }
  ).toList()
  ),
  ),
        Padding(
          padding: const EdgeInsets.all(10.0),
          child: DropdownButton<String>(
              value: dropdownCity,
              icon: Icon(Icons.map),

              style:TextStyle(color: Colors.black, fontSize: 15) ,
              onChanged: (String? newValue) {

                setState(() {
                  dropdownCity = newValue;});
              },
              items: selectedCities.map((String item){
                return DropdownMenuItem<String>(
                  value: item,
                  child: Container(
                    color: Colors.greenAccent,
                    child: Text(item),
                  ),
                );
              }
              ).toList()
          ),
        ),
  ],
  ),
  ),);
}
}

标签: flutterdrop-down-menumulti-level

解决方案


通常,在任何不特定于 dart 或作为颤振下拉按钮功能的语言中,在这种情况下,您将通过数据封装进行中继,您将准备一个国家对象列表,每个对象都包含 ID、名称和他们自己的城市列表

class Country {
   int id;
   String name;
   List<City> cities;
}

class City {
   int id;
   String name;
}

所以在这种情况下,您将有一个 Country 而不是 String 的下拉列表

DropdownButton<Country>
          

而不是长的“if-else if-else ... else”,您将获得城市的直接映射

selectedCities = selectedCountry.cities

推荐阅读