Flutter 选择值[使用api和FutureBuilder中的数据]时出现颤振下拉按钮错误
嘿,伙计们,我正面临一个问题,我正在用这段代码从api检索数据Flutter 选择值[使用api和FutureBuilder中的数据]时出现颤振下拉按钮错误,flutter,dropdownbutton,Flutter,Dropdownbutton,嘿,伙计们,我正面临一个问题,我正在用这段代码从api检索数据 class carLists{ carLists(); getCarsFromNetwork(String jsonUrl) async { List<Cars> list; String link = jsonUrl; var res = await http.get(Uri.encodeFull(link),headers: {"Accept":"Application/json"}); if (res.statu
class carLists{
carLists();
getCarsFromNetwork(String jsonUrl) async {
List<Cars> list;
String link = jsonUrl;
var res = await http.get(Uri.encodeFull(link),headers: {"Accept":"Application/json"});
if (res.statusCode == 200) {
var data = json.decode(res.body);
var list = data["cars"] as List;
List<Cars> imagesList = list.map((i) => Cars.fromJson(i)).toList();
return imagesList;
}
}
List<DropdownMenuItem> getCars(List<Cars> carPlates){
List<DropdownMenuItem<String>> ordersType = new List<DropdownMenuItem<String>>();
for(var i = 0 ; i<carPlates.length;i++ ) {
ordersType.add(DropdownMenuItem(
value: carPlates[i].carPlate, child: Text(carPlates[i].carPlate),));
}
return ordersType;
}
}
值已填充,一切正常,但当我从下拉列表中选择一个值时,它会因此错误而崩溃
I/Flatter 4578:以下断言被抛出building FutureBuilder>dirty,状态:
I/颤振4578:_FutureBuilderState>f394d:
I/flatter 4578:“包:flatter/src/material/dropdown.dart”:失败的断言:第608行位置15:“items==null”||
I/flatter 4578:items.isEmpty | | value==null | | | items.whereDropdownMenuItem=>item.value==
I/颤振4578:value.length==1':不正确。
I/颤振4578:
I/flatter4578:要么断言表明框架本身存在错误,要么我们应该提供
I/颤振4578:此错误消息中的更多信息可帮助您确定并修复根本原因。
I/Flatter 4578:无论哪种情况,请在GitHub上提交一个bug来报告这一断言:
I/颤振4578:
I/颤振4578:
I/flatter 4578:抛出异常时,这是堆栈:
I/颤振4578:2个新的下拉按钮
Container(
child: FutureBuilder(
future: foo(url) ,
builder: (context, snapshot){
if(snapshot.hasData)
{
return new DropdownButton(
iconDisabledColor: Colors.black,
isExpanded: true,
icon: Icon(FontAwesomeIcons.arrowCircleDown),
iconSize: 14,
style: TextStyle(fontSize: 16, color: Colors.black),
iconEnabledColor: Colors.deepOrange,
items: carLists().getCars(carPlates),
value: dropTyreBrand,
onChanged: (val) {
setState(() {
dropTyreBrand = val;
});
},
);
}else{
return CircularProgressIndicator();
}
}
),
) ,
如果使用FutureBuilder和in items,则需要使用snapshot.data 这就是为什么说items==null或者items是空的 演示代码片段
return DropdownButton<Designations>(
items: snapshot.data
.map((designation) => DropdownMenuItem<Designations>(
child: Text(designation.designation),
value: designation,
))
.toList(),
演示完整代码
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
// To parse this JSON data, do
//
// final designations = designationsFromJson(jsonString);
List<Designations> designationsFromJson(String str) => List<Designations>.from(
json.decode(str).map((x) => Designations.fromJson(x)));
String designationsToJson(List<Designations> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Designations {
String designationId;
String designation;
Designations({
this.designationId,
this.designation,
});
factory Designations.fromJson(Map<String, dynamic> json) => Designations(
designationId: json["DesignationId"],
designation: json["Designation"],
);
Map<String, dynamic> toJson() => {
"DesignationId": designationId,
"Designation": designation,
};
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: JsonApiDropdown(),
);
}
}
class JsonApiDropdown extends StatefulWidget {
@override
JsonApiDropdownState createState() {
return new JsonApiDropdownState();
}
}
class JsonApiDropdownState extends State<JsonApiDropdown> {
Designations _currentDesignation;
final String uri = 'https://jsonplaceholder.typicode.com/users';
Future<List<Designations>> _fetchDesignation() async {
String jsonString =
'[ { "DesignationId": "CDG0008", "Designation": "Avp - Associate Vice President" }, { "DesignationId": "CDG0004", "Designation": "Ceo - Chief Executive Officer" } ]';
final designations = designationsFromJson(jsonString);
return designations;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetching data from JSON - DropdownButton'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FutureBuilder<List<Designations>>(
future: _fetchDesignation(),
builder: (BuildContext context,
AsyncSnapshot<List<Designations>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<Designations>(
items: snapshot.data
.map((designation) => DropdownMenuItem<Designations>(
child: Text(designation.designation),
value: designation,
))
.toList(),
onChanged: (Designations value) {
setState(() {
_currentDesignation = value;
});
},
isExpanded: false,
//value: _currentUser,
hint: Text('Select User'),
);
}),
SizedBox(height: 20.0),
_currentDesignation != null
? Text("designation: " +
_currentDesignation.designation +
"\n id: " +
_currentDesignation.designationId)
: Text("No selected"),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() => runApp(MyApp());
// To parse this JSON data, do
//
// final designations = designationsFromJson(jsonString);
List<Designations> designationsFromJson(String str) => List<Designations>.from(
json.decode(str).map((x) => Designations.fromJson(x)));
String designationsToJson(List<Designations> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Designations {
String designationId;
String designation;
Designations({
this.designationId,
this.designation,
});
factory Designations.fromJson(Map<String, dynamic> json) => Designations(
designationId: json["DesignationId"],
designation: json["Designation"],
);
Map<String, dynamic> toJson() => {
"DesignationId": designationId,
"Designation": designation,
};
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: JsonApiDropdown(),
);
}
}
class JsonApiDropdown extends StatefulWidget {
@override
JsonApiDropdownState createState() {
return new JsonApiDropdownState();
}
}
class JsonApiDropdownState extends State<JsonApiDropdown> {
Designations _currentDesignation;
final String uri = 'https://jsonplaceholder.typicode.com/users';
Future<List<Designations>> _fetchDesignation() async {
String jsonString =
'[ { "DesignationId": "CDG0008", "Designation": "Avp - Associate Vice President" }, { "DesignationId": "CDG0004", "Designation": "Ceo - Chief Executive Officer" } ]';
final designations = designationsFromJson(jsonString);
return designations;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Fetching data from JSON - DropdownButton'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
FutureBuilder<List<Designations>>(
future: _fetchDesignation(),
builder: (BuildContext context,
AsyncSnapshot<List<Designations>> snapshot) {
if (!snapshot.hasData) return CircularProgressIndicator();
return DropdownButton<Designations>(
items: snapshot.data
.map((designation) => DropdownMenuItem<Designations>(
child: Text(designation.designation),
value: designation,
))
.toList(),
onChanged: (Designations value) {
setState(() {
_currentDesignation = value;
});
},
isExpanded: false,
//value: _currentUser,
hint: Text('Select User'),
);
}),
SizedBox(height: 20.0),
_currentDesignation != null
? Text("designation: " +
_currentDesignation.designation +
"\n id: " +
_currentDesignation.designationId)
: Text("No selected"),
],
),
),
);
}
}