android - 依赖下拉列表的第二个下拉列表仅在热重新加载后加载数据
问题描述
我正在构建一个依赖下拉列表,要求用户在第一个下拉列表中选择一个省,以便他们能够在第二个下拉列表中选择一个城市。我设法让代码按预期工作,但问题是,第二个下拉列表仅显示在热重新加载后从 API 获取的城市数据,尽管事实上在根据终端。如果我决定重新选择省,同样的事情也适用。我将每个 Dropdownlist 包装在 FutureBuilder 中,因为从 API 获取数据需要一些时间。
省API
Future<ProvinceModel> getProvince() async {
var response = await http.get(Uri.parse(
'https://rs-bed-covid-api.vercel.app/api/get-provinces'
));
if(response.statusCode == 200) {
print(response.body);
return ProvinceModel.fromJson(json.decode(response.body));
}
else {
throw Exception(
'Something Went Wrong'
);
}
}
城市API
Future<CityModel> getCity(String id) async {
var response = await http.get(Uri.parse(
'https://rs-bed-covid-api.vercel.app/api/get-cities?provinceid=' + id
));
print(id);
if(response.statusCode == 200) {
print(response.body);
return CityModel.fromJson(json.decode(response.body));
}
else {
throw Exception(
'Something Went Wrong'
);
}
}
省模式
class ProvinceModel {
ProvinceModel({
this.provinces,
});
List<Province> provinces;
factory ProvinceModel.fromJson(Map<String, dynamic> json) =>
ProvinceModel(
provinces: List<Province>.from(json["provinces"].map((x) =>
Province.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"provinces": List<dynamic>.from(provinces.map((x) =>
x.toJson())),
};
}
class Province {
Province({
this.id,
this.name,
});
String id;
String name;
factory Province.fromJson(Map<String, dynamic> json) => Province(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
城市模型
class CityModel {
CityModel({
this.cities,
});
List<City> cities;
factory CityModel.fromJson(Map<String, dynamic> json) => CityModel(
cities: List<City>.from(json["cities"].map((x) =>
City.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"cities": List<dynamic>.from(cities.map((x) => x.toJson())),
};
}
class City {
City({
this.id,
this.name,
});
String id;
String name;
factory City.fromJson(Map<String, dynamic> json) => City(
id: json["id"],
name: json["name"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
};
}
这是主要代码,
class HomeScreen extends StatefulWidget {
static Future province;
static Future city;
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
ProvinceRepository provinceRepository = new ProvinceRepository();
@override
void initState() {
super.initState();
HomeScreen.province = provinceRepository.getProvince();
HomeScreen.city = _CityDropDownState().getCity("id");
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Container(
padding: const EdgeInsets.fromLTRB(16, 30, 16, 5),
child: Center(
child: Container(
height: 250,
width: 400,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white
),
child: Column(
children: [
FutureBuilder<ProvinceModel>(
future: HomeScreen.province,
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
padding: const EdgeInsets.only(top: 70),
alignment: Alignment.center,
child: Column(
children: [
CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
SizedBox(height: 15),
Text(
'Mohon Tunggu Sebentar...',
style: TextStyle(
color: Colors.red,
fontSize: 15,
fontWeight: FontWeight.bold
),
)
],
),
);
}
else {
return Container(
width: 300,
padding: const EdgeInsets.only(top: 50),
child: ProvinceDropDown(
province: snapshot.data,
),
);
}
}
),
SizedBox(height: 10),
FutureBuilder<CityModel>(
future: HomeScreen.city,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Container(
alignment: Alignment.center,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.red),
),
);
}
else if (snapshot.data == null) {
return Container();
}
else if (snapshot.hasData){
return Container(
width: 300,
child: CityDropDown(
city: snapshot.data,
),
);
}
else {
return null;
}
}
),
],
),
),
),
),
);
}
}
省份下拉
class ProvinceDropDown extends StatefulWidget {
final ProvinceModel province;
static var selectedProvince;
const ProvinceDropDown({ Key key, this.province }) : super(key: key);
@override
_ProvinceDropDownState createState() => _ProvinceDropDownState();
}
class _ProvinceDropDownState extends State<ProvinceDropDown> {
List<Province> provinceList;
@override
void initState() {
provinceList = widget.province.provinces;
super.initState();
}
@override
Widget build(BuildContext context) {
return DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<Province>(
hint: Text(
'PROVINSI'
),
isExpanded: true,
items: provinceList.map((item) {
return DropdownMenuItem<Province>(
child: Text(item.name),
value: item,
);
}).toList(),
onChanged: (Province value) {
setState(() {
CityDropDown.selectedCity = null;
ProvinceDropDown.selectedProvince = value;
HomeScreen.city = _CityDropDownState().getCity(ProvinceDropDown.selectedProvince.id);
});
},
value: ProvinceDropDown.selectedProvince,
),
),
);
}
}
城市下拉
class CityDropDown extends StatefulWidget {
final CityModel city;
static var selectedCity;
const CityDropDown({ Key key, this.city }) : super(key: key);
@override
_CityDropDownState createState() => _CityDropDownState();
}
class _CityDropDownState extends State<CityDropDown> {
List<City> cityList;
@override
void initState() {
super.initState();
cityList = widget.city.cities;
}
@override
Widget build(BuildContext context) {
return Column(
children: [
DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton<City>(
hint: Text(
'KOTA/KABUPATEN'
),
isExpanded: true,
items: cityList.map((item) {
return DropdownMenuItem<City>(
child: Text(item.name),
value: item,
);
}).toList(),
onChanged: (City value) {
setState(() {
CityDropDown.selectedCity = value;
});
},
value: CityDropDown.selectedCity,
),
),
),
SizedBox(height: 10),
InkWell(
onTap: () {
if(CityDropDown.selectedCity == null) {
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
content: Text(
'Tolong pilih sebuah Kota atau Kabupaten',
textAlign: TextAlign.center,
),
);
}
);
}
else {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return HospitalScreen(
provinceID: ProvinceDropDown.selectedProvince.id,
cityID: CityDropDown.selectedCity.id,
);
})
);
}
},
child: Container(
margin: const EdgeInsets.only(top: 20),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.red
),
child: Text(
'CARI',
style: TextStyle(
color: Colors.white,
fontSize: 16
),
),
),
)
],
);
}
}
抱歉,代码很长,我的问题是如何让 City Drop Down 显示获取的数据而无需热重新加载我的应用程序?提前致谢
解决方案
推荐阅读
- java - 事件处理程序和 setOnAction?
- javascript - 如何删除小于给定值但不是最后一个值的值?
- database - 使一对多关系适应 DynamoDB (NoSQL)
- sql - SQL 获得同比季度至今的收入
- python - 当我在 django 版本 2.1.4 中定义 URL 模式时,出现错误。请告诉我一条路
- javascript - 如何让机器人在不带'\_poll'的情况下发送投票消息,以获取带有discord.js的adv poll命令
- python - 如何计算两个 ISO 日期之间的周数
- python - 如何在python中创建数据结构二进制文件?
- python - 如何将文件输出格式化为特定数量的数据列?
- excel - VBA:SelectAll之后的选择焦点