Flutter 颤振-如何使用返回和对象数组的未来填充下拉按钮
Flatter和dart的新手,正在努力从返回对象的api填充此下拉列表,并且在对象中有一个对象的数据数组。看起来像:Flutter 颤振-如何使用返回和对象数组的未来填充下拉按钮,flutter,dart,types,Flutter,Dart,Types,Flatter和dart的新手,正在努力从返回对象的api填充此下拉列表,并且在对象中有一个对象的数据数组。看起来像: { "data": [ { "Country_str_code": "AL", "Region_str_code": "Eur", "Country_str_name": "A
{
"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。这样编译器就不会抱怨了。运行整个代码,看看它是否按照您希望的方式工作。谢谢!是的,这很管用,但是如果我想要我呢