选择值时出现Flutter dropdownbutton错误[使用api和FutureBuilder中的数据]

时间:2019-09-17 14:59:55

标签: 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.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;
}

}

并使用这两个函数实现一个dropdownbutton来获取数据并返回dropdownmenuitem列表:

Future<List<Cars>> foo(String link) async{

carPlates =  await carLists().getCarsFromNetwork(link);
print(carPlates.length);
return carPlates;
}

getItems(List values) {
List<DropdownMenuItem<String>> ordersType = new List<
    DropdownMenuItem<String>>();
for (var i = 0; i > values.length; i++) {
  ordersType.add(DropdownMenuItem(value: values[i], child: values[i],));

  return ordersType;
}
}

`,并使用此代码填充DropdownButton

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();

     }
        }
    ),
  ) ,

这些值已填充并且一切都很好,但是当我从下拉列表中选择一个值时,它会因该错误而崩溃

  

I / flutter(4578):构建FutureBuilder时引发了以下断言>(脏,状态:   我/颤振(4578):_FutureBuilderState>#f394d):   I / flutter(4578):'package:flutter / src / material / dropdown.dart':失败的断言:第608行pos 15:'item == null ||   I / flutter(4578):item.isEmpty ||值== null || items.where(((DropdownMenuItem item)=> item.value ==   I / flutter(4578):值).length == 1':不正确。   I /颤振(4578):   I / flutter(4578):要么断言表明框架本身有错误,要么我们应该提供   I / flutter(4578):此错误消息中的更多信息可帮助您确定和解决根本原因。   I / flutter(4578):无论哪种情况,请通过在GitHub上提交错误来报告此断言:   I / flutter(4578):https://github.com/flutter/flutter/issues/new?template=BUG.md   I /颤振(4578):   I / flutter(4578):引发异常时,这是堆栈:   I / flutter(4578):#2新的DropdownButton

1 个答案:

答案 0 :(得分:0)

如果使用FutureBuilder,并且在项目中需要使用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"),
          ],
        ),
      ),
    );
  }
}

enter image description here