颤振中的多级下拉按钮——我们可以消除 if 语句吗?
Multi-level dropdown buttons in flutter - can we eliminate the if statements?
我实现了两级下拉按钮,其中按钮 # 2 取决于按钮 #1 的选择。第一个下拉列表是国家/地区列表,根据用户对国家/地区的选择,第二个下拉列表中将提供城市列表。主要问题是关于两个下拉列表之间的 link,我正在使用一系列 if 语句来告诉代码如果我选择国家 x,则显示 x 的城市等。
在下面的示例代码中,我只包括了 6 个国家,因此编写 if 语句仍然很干净且易于管理,但是如果国家列表达到 150 个怎么办?我需要将 150 行 if 语句写到 link 个国家的城市吗?有没有更聪明的方法来做到这一点?我可以利用国家名称和包含其城市的列表名称的相似性吗?例如'USA' 和 'cityUSA'
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()
),
),
],
),
),);
}
}
通常,在任何不特定于 dart 的语言中或作为 flutter 下拉按钮功能,在这种情况下,您将传递数据 encapsulation,您将准备国家对象列表, 他们每个人都包含 id, name 和他们自己的城市列表
class Country {
int id;
String name;
List<City> cities;
}
class City {
int id;
String name;
}
所以在这种情况下,您将看到一个国家/地区下拉列表,而不是字符串
DropdownButton<Country>
而不是长长的“if-else if-else ... else”,你将有一个城市的直接映射
selectedCities = selectedCountry.cities
我实现了两级下拉按钮,其中按钮 # 2 取决于按钮 #1 的选择。第一个下拉列表是国家/地区列表,根据用户对国家/地区的选择,第二个下拉列表中将提供城市列表。主要问题是关于两个下拉列表之间的 link,我正在使用一系列 if 语句来告诉代码如果我选择国家 x,则显示 x 的城市等。 在下面的示例代码中,我只包括了 6 个国家,因此编写 if 语句仍然很干净且易于管理,但是如果国家列表达到 150 个怎么办?我需要将 150 行 if 语句写到 link 个国家的城市吗?有没有更聪明的方法来做到这一点?我可以利用国家名称和包含其城市的列表名称的相似性吗?例如'USA' 和 'cityUSA'
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()
),
),
],
),
),);
}
}
通常,在任何不特定于 dart 的语言中或作为 flutter 下拉按钮功能,在这种情况下,您将传递数据 encapsulation,您将准备国家对象列表, 他们每个人都包含 id, name 和他们自己的城市列表
class Country {
int id;
String name;
List<City> cities;
}
class City {
int id;
String name;
}
所以在这种情况下,您将看到一个国家/地区下拉列表,而不是字符串
DropdownButton<Country>
而不是长长的“if-else if-else ... else”,你将有一个城市的直接映射
selectedCities = selectedCountry.cities