Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter 颤振-如何使用返回和对象数组的未来填充下拉按钮_Flutter_Dart_Types - Fatal编程技术网

Flutter 颤振-如何使用返回和对象数组的未来填充下拉按钮

Flutter 颤振-如何使用返回和对象数组的未来填充下拉按钮,flutter,dart,types,Flutter,Dart,Types,Flatter和dart的新手,正在努力从返回对象的api填充此下拉列表,并且在对象中有一个对象的数据数组。看起来像: { "data": [ { "Country_str_code": "AL", "Region_str_code": "Eur", "Country_str_name": "A

Flatter和dart的新手,正在努力从返回对象的api填充此下拉列表,并且在对象中有一个对象的数据数组。看起来像:

{
    "data": [
         {
        "Country_str_code": "AL",
        "Region_str_code": "Eur",
        "Country_str_name": "Albania"
    },
    {
        "Country_str_code": "DZ",
        "Region_str_code": "Afr",
        "Country_str_name": "Algeria"
    },
  ]
}
下面是我的小部件的代码。我只想显示国家名称,但不确定我是否需要在下拉列表中的国家代码,所以保存在提交它。我甚至不能把这个展示出来。我得到了这个错误:

import 'dart:async';
import 'dart:convert';
   
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'register.dart';
    
Future<List<Country>> fetchCountries() async {
  final response = await http.get(Uri.https('localhost/msd', '/api/countries'));
  final responseJson = json.decode(response.body);

  print(responseJson['data']);

  if (response.statusCode == 200) {
 
  return (responseJson['data'] as List<Country>)
    .map((country) => country);
  } else {
    throw Exception('Failed to load countries');
  }
}

class Country {
  final String countryCode;
  final String countryName;

  Country({@required this.countryCode, @required this.countryName});

  factory Country.fromJson(Map<String, dynamic> json) {
    var countrNameFromJson = json['Country_str_name'];
    var countrCodeFromJson = json['Country_str_code'];
    String castedCountryName = countrNameFromJson.cast<String>();
    String castedCountryCode = countrCodeFromJson.cast<String>();
    return Country(
      countryCode: castedCountryCode,
      countryName: castedCountryName
    );
  }
}

class Location extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return LocationState();
  }

}

class LocationState extends State<Location> {
  Future<List<Country>> futureCountry;
  Map<String, dynamic> _selected = {'countryCode': '', 'countryName':'Select Country'};

  @override
  void initState() {
    super.initState();
    futureCountry = fetchCountries();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Registrate'),
        backgroundColor: Colors.blue[600],
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Center(
            child:  FutureBuilder<List<Country>>(
              future: futureCountry,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  print (snapshot.data);
                  return DropdownButton(
                    value: _selected,
                    icon: Icon(Icons.arrow_drop_down),
                    iconSize: 30, 
                    elevation: 16,
                    style: TextStyle(color: Colors.black),
                    onChanged: (newValue) {
                      setState(() {
                        _selected = newValue;
                      });
                    },
                    items: snapshot.data
                      .map<DropdownMenuItem<String>>((Country value) {
                        return DropdownMenuItem<String>(
                          value: value.countryCode,
                          child: Text(value.countryName),
                        );
                    }).toList(),
                  );
                } else if (snapshot.hasError) {
                  return Text("${snapshot.error}");
                }
                return CircularProgressIndicator();
              },
            ),
          ),
          SizedBox(
            width: double.maxFinite,
            child: ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => Register())
                );
              },
              child: Text('Continue'),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(Colors.red[900]),
                foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
              )
            ),
          ),
        ],
      ),
    );
  }
}
type 'List<dynamic> is not a subtype of type 'List<Country>' in type cast
导入'dart:async';
导入“dart:convert”;
进口“包装:颤振/材料.省道”;
将“package:http/http.dart”导入为http;
导入“register.dart”;
Future fetchCountries()异步{
最终响应=等待http.get(Uri.https('localhost/msd','/api/countries');
final responseJson=json.decode(response.body);
打印(应答[“数据]);
如果(response.statusCode==200){
返回(responseJson['data']作为列表)
.地图((国家)=>国家);
}否则{
抛出异常(“加载国家/地区失败”);
}
}
阶级国家{
最终字符串国家代码;
最后一个字符串countryName;
国家({@required this.countryCode,@required this.countryName});
factory Country.fromJson(映射json){
var countrNameFromJson=json['Country_str_name'];
var countrCodeFromJson=json['Country_str_code'];
字符串castedCountyName=countrNameFromJson.cast();
String castedCountryCode=countrCodeFromJson.cast();
返回国(
国家代码:castedCountryCode,
国家名称:castedCountryName
);
}
}
类位置扩展了StatefulWidget{
@凌驾
状态createState(){
返回位置状态();
}
}
类LocationState扩展了状态{
未来国家;
地图_selected={'countryCode':'','countryName':'selectcountry'};
@凌驾
void initState(){
super.initState();
futureCountry=fetchCountries();
}
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(“注册”),
背景颜色:颜色。蓝色[600],
),
正文:专栏(
crossAxisAlignment:crossAxisAlignment.start,
儿童:[
居中(
孩子:未来建设者(
未来:未来国家,
生成器:(上下文,快照){
if(snapshot.hasData){
打印(快照数据);
返回下拉按钮(
值:_已选定,
图标:图标(图标。箭头下拉),
iconSize:30,
海拔:16,
样式:TextStyle(颜色:Colors.black),
一旦更改:(newValue){
设置状态(){
_所选=新值;
});
},
项目:snapshot.data
.map((国家/地区值){
返回下拉菜单项(
value:value.countryCode,
子项:文本(value.countryName),
);
}).toList(),
);
}else if(snapshot.hasrerror){
返回文本(“${snapshot.error}”);
}
返回循环ProgressIndicator();
},
),
),
大小盒子(
宽度:double.maxFinite,
儿童:升降按钮(
已按下:(){
导航器。推(
上下文
MaterialPage路由(生成器:(上下文)=>Register()
);
},
子项:文本('Continue'),
样式:钮扣样式(
背景色:MaterialStateProperty.all(Colors.red[900]),
foregroundColor:MaterialStateProperty.all(颜色.白色),
)
),
),
],
),
);
}
}
当前正在获取此错误:

import 'dart:async';
import 'dart:convert';
   
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'register.dart';
    
Future<List<Country>> fetchCountries() async {
  final response = await http.get(Uri.https('localhost/msd', '/api/countries'));
  final responseJson = json.decode(response.body);

  print(responseJson['data']);

  if (response.statusCode == 200) {
 
  return (responseJson['data'] as List<Country>)
    .map((country) => country);
  } else {
    throw Exception('Failed to load countries');
  }
}

class Country {
  final String countryCode;
  final String countryName;

  Country({@required this.countryCode, @required this.countryName});

  factory Country.fromJson(Map<String, dynamic> json) {
    var countrNameFromJson = json['Country_str_name'];
    var countrCodeFromJson = json['Country_str_code'];
    String castedCountryName = countrNameFromJson.cast<String>();
    String castedCountryCode = countrCodeFromJson.cast<String>();
    return Country(
      countryCode: castedCountryCode,
      countryName: castedCountryName
    );
  }
}

class Location extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return LocationState();
  }

}

class LocationState extends State<Location> {
  Future<List<Country>> futureCountry;
  Map<String, dynamic> _selected = {'countryCode': '', 'countryName':'Select Country'};

  @override
  void initState() {
    super.initState();
    futureCountry = fetchCountries();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Registrate'),
        backgroundColor: Colors.blue[600],
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Center(
            child:  FutureBuilder<List<Country>>(
              future: futureCountry,
              builder: (context, snapshot) {
                if (snapshot.hasData) {
                  print (snapshot.data);
                  return DropdownButton(
                    value: _selected,
                    icon: Icon(Icons.arrow_drop_down),
                    iconSize: 30, 
                    elevation: 16,
                    style: TextStyle(color: Colors.black),
                    onChanged: (newValue) {
                      setState(() {
                        _selected = newValue;
                      });
                    },
                    items: snapshot.data
                      .map<DropdownMenuItem<String>>((Country value) {
                        return DropdownMenuItem<String>(
                          value: value.countryCode,
                          child: Text(value.countryName),
                        );
                    }).toList(),
                  );
                } else if (snapshot.hasError) {
                  return Text("${snapshot.error}");
                }
                return CircularProgressIndicator();
              },
            ),
          ),
          SizedBox(
            width: double.maxFinite,
            child: ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => Register())
                );
              },
              child: Text('Continue'),
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(Colors.red[900]),
                foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
              )
            ),
          ),
        ],
      ),
    );
  }
}
type 'List<dynamic> is not a subtype of type 'List<Country>' in type cast
type“List”不是类型转换中类型“List”的子类型

有人能给我指点指点一下吗,因为错误清楚地表明这是类型的问题,但我不确定如何解决这个问题。

类型的问题是,在映射
responseJson['data']
的内容之前,它不是一个国家/地区对象的列表,而是动态的,你在试图扮演国家角色后调用map,因此出现了错误

  return (responseJson['data'] as List<Country>)
    .map((country) => country);
您可能还想知道为什么在映射之后调用
toList()
方法,这是因为map函数返回的是Iterable而不是List

我已经更正了您共享的代码片段,您只需复制/粘贴它,看看它是如何工作的(为了不让您的本地主机进行测试,我删除了http代码)
(responseJson['data'] as List<Country>)
这是非常容易出错的手动操作,不建议这样做。建议使用代码生成器根据为您创建序列化/反序列化类/方法


这里还有一些。

感谢您的回答。这有助于解决铸造问题,但现在我陷入了另一个错误,即下拉选择值。应该只有一个项目具有[DropdownButtons]的值:Select。零或2或更多[DropdownMenuItems]检测到具有相同值的。猜测它与所选值有关,但不确定如何解决它。无论我怎么做,它都会导致不同的错误。过去我只能使用字符串数组来执行此操作,并且必须确保初始选定值也是主数组的一部分,但在本例中,不确定要执行什么操作。also每个项目都是一个对象,不确定我是否还必须将该对象传递到下拉列表或sting,不管我做了什么,它总是抱怨:-)检查我答案中的代码,我将选择的值更改为Country,而不是初始值为null(未选择)的Map。这样编译器就不会抱怨了。运行整个代码,看看它是否按照您希望的方式工作。谢谢!是的,这很管用,但是如果我想要我呢