问题
Hello i am work with flutter drop down menu . firs menu for location . and second for sublocation . it is work when click on first location but when change to second and click second location this error appear "'package:flutter/src/material/dropdown.dart': Failed assertion: line 620 pos 15: 'items == null || items.isEmpty || value == null || items.where((DropdownMenuItem item) => item.value == value).length == 1': is not true. "
my variable
//location
String _myLocation ;
List data = List();
//sublocation
String _mySublocation ;
List data2 = List();
function for location
Future getLocation() async {
try{
var res = await http
.get(Uri.encodeFull("http://iraqdoctors.com/api/locations"), headers: {"Accept": "application/json"});
setState(() {
var resBody = json.decode(res.body);
data = resBody;
});
return "Sucess";
}catch(e){
}
}//get location
function for sublocation
Future getSublocation() async {
try{
var res2 = await http
.post(Uri.encodeFull("http://iraqdoctors.com/api/getlocationflutter"),
headers: {"Accept": "application/json"},
body: {
"cityname":"$_myLocation",
}
);
setState(() {
var resBody2 = json.decode(res2.body);
data2 = resBody2;
});
return "Sucess";
}catch(e){
}
}//get sublocation
Location dropdown
Container(
padding: EdgeInsets.only(right:10),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
child:DropdownButton( //location
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 18),
value: _myLocation,
items: data.map((item) {
return new DropdownMenuItem(
child: Text(item['city'],style: TextStyle(color: Colors.black)),
value: item['city'],
);
}).toList(),
onChanged: ( newVal) {
setState(() {
_myLocation = newVal;
getSublocation();
});
},
isExpanded: true,
underline: SizedBox(),
iconEnabledColor: Colors.white,
hint: Text('اختر المدينة',style: TextStyle(color: Colors.black),),
),),
Sublocation dropdown
Container(
padding: EdgeInsets.only(right:10),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
child: DropdownButton(//sublocation
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 18) ,
items: data2.map((item) {
return new DropdownMenuItem(
child: Text(item['state'],style: TextStyle(color: Colors.black)),
value: item['id'].toString(),
);
}).toList(),
onChanged: (value) {
setState(() {
_mySublocation = value ;
});
},
value: _mySublocation ,
isExpanded: true,
hint: Text('اختر المنطقة',style: TextStyle(color: Colors.black),),
underline: SizedBox(),
iconEnabledColor: Colors.white,
),),
```
回答1:
itry your code but still same error when load sublocation menu
回答2:
You can copy paste run full code below
I use 2 seconds delay to simulate your http task
The error message means data2 is null
In your onChanged, you need to await await getSublocation()
and make sure convert json to data2 is correct
code snippet
onChanged: (newVal) async {
_myLocation = newVal;
await getSublocation();
setState(() {});
},
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
String _myLocation = null;
List data = List();
//sublocation
String _mySublocation = null;
List data2 = List();
Future getLocation() async {
try {
/* var res = await http.get(
Uri.encodeFull("http://iraqdoctors.com/api/locations"),
headers: {"Accept": "application/json"});
setState(() {
var resBody = json.decode(res.body);
data = resBody;
});*/
await Future.delayed(const Duration(seconds: 1), () {});
data.clear();
data.add({"city": "A"});
data.add({"city": "B"});
setState(() {});
return "Sucess";
} catch (e) {}
} //get location
Future getSublocation() async {
try {
/*var res2 = await http.post(
Uri.encodeFull("http://iraqdoctors.com/api/getlocationflutter"),
headers: {
"Accept": "application/json"
},
body: {
"cityname": "$_myLocation",
});
setState(() {
var resBody2 = json.decode(res2.body);
data2 = resBody2;
});*/
await Future.delayed(const Duration(seconds: 2), () {});
String jsonString = '''
[ { "id": 1, "state": "الحارثية", "city": "بغداد", "created_at": "2019-12-17 07:20:16", "updated_at": "2019-12-17 07:20:16" } ]
''';
data2.clear();
data2 = json.decode(jsonString);
/*data2.clear();
data2.add({"state": "A1", "id": "a1"});
data2.add({"state": "B1", "id": "b1"});*/
print(data2.toString());
print(data2[0]['state'].toString());
setState(() {});
return "Sucess";
} catch (e) {
print(e.toString());
}
} //get sublocation
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
getLocation();
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Container(
padding: EdgeInsets.only(right: 10),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
child: DropdownButton(
//location
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 18),
value: _myLocation,
items: data.map((item) {
return new DropdownMenuItem(
child: Text(' ${item['city']} ',
style: TextStyle(color: Colors.black)),
value: item['city'],
);
}).toList(),
onChanged: (newVal) async {
_myLocation = newVal;
await getSublocation();
setState(() {});
},
isExpanded: true,
underline: SizedBox(),
iconEnabledColor: Colors.white,
hint: Text(
'اختر المدينة',
style: TextStyle(color: Colors.black),
),
),
),
Container(
padding: EdgeInsets.only(right: 10),
decoration: ShapeDecoration(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(8.0)),
),
),
child: DropdownButton(
//sublocation
icon: Icon(Icons.arrow_drop_down),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.black, fontSize: 18),
items: data2.map((item) {
return new DropdownMenuItem(
child: Text(' ${item['state']}',
style: TextStyle(color: Colors.black)),
value: item['id'].toString(),
);
}).toList(),
onChanged: (value) {
setState(() {
_mySublocation = value;
});
},
value: _mySublocation,
isExpanded: true,
hint: Text(
'اختر المنطقة',
style: TextStyle(color: Colors.black),
),
underline: SizedBox(),
iconEnabledColor: Colors.white,
),
),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
来源:https://stackoverflow.com/questions/59604124/flutter-i-have-error-when-work-with-tow-dropdown-button-load-one-from-another