我刚刚开始学习颤动。
我有两个DropdownButtons,我试图根据区域json中cid对第一个过滤的选择来填充第二个。
{"countries":[{"cid":"2","name":"Country A"},{"cid":"3","name":"Country B"}]}
{"regions":[{"rid":"1","cid":"2","name":"Region 1 of Country A"},{"rid":"2","cid":"2","name":"Region 2 of Country A"},{"rid":"3","cid":"3","name":"Region 1 of Country B"},{"rid":"4","cid":"3","name":"Region 2 of Country B"}]}
void main () {
runApp(new SearchAssembly());
}
class SearchAssembly extends StatefulWidget{
SearchAssembly({Key key}):super(key:key);
@override
_SearchAssemblyState createState() => new _SearchAssemblyState ();
}
class _SearchAssemblyState extends State<SearchAssembly> {
List _countryData = new List();
List _regionData = new List();
List<DropdownMenuItem<String>> _dropDownMenuItemsCountries;
List<DropdownMenuItem<String>> _dropDownMenuItemsRegions;
String _selectedCountry;
String _selectedRegion;
Future<List> getCountry() async{
http.Response response = await http.get(countryUrl);
var results= await json.decode(response.body)['countries'];
return results;
}
Future<List> getRegions() async{
http.Response response = await http.get(regionsUrl);
var results= await json.decode(response.body)['regions'];
return results;
}
void loadData () async{
_countryData = await getCountry();
_regionData = await getRegions();
setState(() {
_selectedCountry="2";
_selectedRegion="1";
_dropDownMenuItemsCountries = getDropDownMenuItemCountries();
_dropDownMenuItemsRegions=getDropDownMenuItemRegions(_selectedCountry);
});
}
@override
void initState() {
loadData ();
super.initState();
}
List<DropdownMenuItem<String>> getDropDownMenuItemCountries( ) {
List<DropdownMenuItem<String>> items = new List();
if (_countryData.isNotEmpty) {
for (int i = 0; i < _countryData.length; i++) {
String cid= _countryData[i]['cid'].toString();
String name=_countryData[i]['name'].toString();
items.add(new DropdownMenuItem(value: cid,
child: new Text(name)
));
}
}
return items;
}
void changeDropDownItemCountry(String selectedCountry){
setState(() {
_selectedCountry=selectedCountry;
_dropDownMenuItemsRegions =
getDropDownMenuItemRegions(_selectedCountry);
});
}
List<DropdownMenuItem<String>> getDropDownMenuItemRegions(String filterBy)
{
List<DropdownMenuItem<String>> items = new List();
if(_regionData.isNotEmpty) {
for (int i = 0; i < _regionData.length; i++) {
if (_regionData[i]['cid'].toString() == filterBy) {
String rid = _regionData[i]['rid'].toString();
String name = _regionData[i]['name'].toString();
items.add(new DropdownMenuItem(value: rid,
child: new Text(name)
));
}
}
}
return items;
}
void changeDropDownItemRegion(String selectedRegion){
setState(() {
_selectedRegion=selectedRegion;
print ("The selected Region is: $_selectedRegion");
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(" Locator"),
elevation: 0.1,
backgroundColor: new Color(0xFF546E7A),
),
backgroundColor: Colors.blueGrey.shade500,
body: ListView(
padding: const EdgeInsets.all(10.0),
children: <Widget>[
new DropdownButtonHideUnderline(child:
new DropdownButton(
value: _selectedCountry,
items: _dropDownMenuItemsCountries,
onChanged: changeDropDownItemCountry,
isExpanded: true,
isDense: true,
),
),
new SizedBox(
child: null,height: 10.0,
),
new DropdownButtonHideUnderline(child:
new DropdownButton(
value: _selectedRegion,
items: _dropDownMenuItemsRegions,
onChanged: changeDropDownItemRegion,
isExpanded: true,
isDense: true,
),
)
],
)
));
}
}
错误:
I/flutter ( 6426): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 6426): The following assertion was thrown building SearchAssembly(dirty, state:
I/flutter ( 6426): _SearchAssemblyState#4c4ac):
I/flutter ( 6426): 'package:flutter/src/material/dropdown.dart': Failed assertion: line 514 pos 15: 'items == null ||
I/flutter ( 6426): value == null || items.where((DropdownMenuItem<T> item) => item.value == value).length == 1': is not
I/flutter ( 6426): true.
I/flutter ( 6426):
I/flutter ( 6426): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter ( 6426): more information in this error message to help you determine and fix the underlying cause.
I/flutter ( 6426): In either case, please report this assertion by filing a bug on GitHub:
I/flutter ( 6426): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter ( 6426):
I/flutter ( 6426): When the exception was thrown, this was the stack:
I/flutter ( 6426): #2 new DropdownButton (package:flutter/src/material/dropdown.dart:514:15)
I/flutter ( 6426): #3 _SearchAssemblyState.build (package:flutter_dashboard/search_assembly_widget.dart:212:16)
I/flutter ( 6426): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter ( 6426): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter ( 6426): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter ( 6426): #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter ( 6426): #8 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
I/flutter ( 6426): #9 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter ( 6426): #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter ( 6426): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter ( 6426): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter ( 6426): #13 _invoke (dart:ui/hooks.dart:154:13)
I/flutter ( 6426): #14 _drawFrame (dart:ui/hooks.dart:143:3)
I/flutter ( 6426): (elided 2 frames from class _AssertionError)
I/flutter ( 6426): ════════════════════════════════════════════════════════════════════════════════════════════════════
答案 0 :(得分:0)
发生问题是因为_selectedRegion
没有更新。
List<DropdownMenuItem<String>> getDropDownMenuItemRegions(String filterBy) {
List<DropdownMenuItem<String>> items = new List();
if (_regionData.isNotEmpty) {
for (int i = 0; i < _regionData.length; i++) {
if (_regionData[i]['cid'] == filterBy) {
print(_regionData[i]['cid']);
String rid = _regionData[i]['rid'];
String name = _regionData[i]['name'];
setState(() {
_selectedRegion = _regionData[i]['rid'];
});
items.add(new DropdownMenuItem(value: rid, child: new Text(name)));
}
}
}
return items;
}
此DropdownMenuItem
中的最后一项