使用How to Create DropdownButton with a list of JSON Data and I want it to populate my DropDownButton in Flutter中的示例,我创建了以下工作示例:
main.dart
import 'package:flutter/material.dart';
import 'dart:convert';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final String jsonData =
'[{"id":"e20c","name":"Apples","type":"fruit"},{"id":"a24e","name":"Oranges","type":"fruit"},{"id":"f2a0","name":"Bananas","type":"fruit"}]';
List<FruitResponse> _fruitResponse = [];
String selectedName;
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
final json = JsonDecoder().convert(jsonData);
_fruitResponse = (json)
.map<FruitResponse>((item) => FruitResponse.fromJson(item))
.toList();
return MaterialApp(
title: 'Pick Fruit',
home: Scaffold(
appBar: AppBar(
title: Text("Pick Fruit"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
DropdownButtonHideUnderline(
child: DropdownButton<String>(
hint: Text("Select Fruit"),
value: selectedName,
isDense: true,
onChanged: (String newValue) {
setState(() {
selectedName = newValue;
});
print(selectedName);
},
items: _fruitResponse.map((FruitResponse map) {
return DropdownMenuItem<String>(
value: map.nameDescription,
child: Text(map.nameDescription),
);
}).toList(),
)),
],
),
),
));
}
}
class FruitResponse {
final String nameid;
final String nameDescription;
FruitResponse({this.nameid, this.nameDescription});
factory FruitResponse.fromJson(Map<String, dynamic> json) {
return new FruitResponse(nameid: json['id'], nameDescription: json['name']);
}
}
但是,我的JSON数据将是
{"objects":[{"id":"e20c","name":"Apples","type":"fruit"},{"id":"a24e","name":"Oranges","type":"fruit"},{"id":"f2a0","name":"Bananas","type":"fruit"}],"from":1,"to":3,"total":3}
我已经使用https://app.quicktype.io/生成了以下内容
FruitResponse fruitResponseFromJson(String str) => FruitResponse.fromJson(json.decode(str));
String fruitResponseToJson(FruitResponse data) => json.encode(data.toJson());
class FruitResponse {
List<Object> objects;
int from;
int to;
int total;
FruitResponse({
this.objects,
this.from,
this.to,
this.total,
});
factory FruitResponse.fromJson(Map<String, dynamic> json) => FruitResponse(
objects: List<Object>.from(json["objects"].map((x) => Object.fromJson(x))),
from: json["from"],
to: json["to"],
total: json["total"],
);
Map<String, dynamic> toJson() => {
"objects": List<dynamic>.from(objects.map((x) => x.toJson())),
"from": from,
"to": to,
"total": total,
};
}
class Object {
String id;
String name;
String type;
Object({
this.id,
this.name,
this.type,
});
factory Object.fromJson(Map<String, dynamic> json) => Object(
id: json["id"],
name: json["name"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"type": type,
};
}
当我用更新后的类FruitResponse替换类FruitResponse并更改项目映射时,出现错误。
类'_InternalLinkedHashMap'没有匹配的实例方法'map'
此处https://dartpad.dev/b54d896aa35c159cd1749d5c67db7d52
在DartPad中的工作示例此处DartPad中的非工作示例 https://dartpad.dev/0413fb4bb7944ccd378b9eabf4e88ff3
我认为问题只是从json数据正确获取List<Object>
名称,并在DropDownButton项目值中使用它。我知道map.objects.toString()
是不正确的,但是我不知道该放在哪里,或者我是否缺少_fruitResponse。
在此先感谢您的帮助。我正在努力理解映射JSON响应列表数据的过程。
答案 0 :(得分:2)
只需查看下面我使用json创建的示例,我已经在本地解析了json:
以下是json:
{
"objects": [
{
"id": "e20c",
"name": "Apples",
"type": "fruit"
},
{
"id": "a24e",
"name": "Oranges",
"type": "fruit"
},
{
"id": "f2a0",
"name": "Bananas",
"type": "fruit"
}
],
"from": 1,
"to": 3,
"total": 3
}
根据json,我创建了模型类:
// To parse this JSON data, do
//
// final fruitResponse = fruitResponseFromJson(jsonString);
import 'dart:convert';
FruitResponse fruitResponseFromJson(String str) => FruitResponse.fromJson(json.decode(str));
String fruitResponseToJson(FruitResponse data) => json.encode(data.toJson());
class FruitResponse {
List<Object> objects;
int from;
int to;
int total;
FruitResponse({
this.objects,
this.from,
this.to,
this.total,
});
factory FruitResponse.fromJson(Map<String, dynamic> json) => FruitResponse(
objects: List<Object>.from(json["objects"].map((x) => Object.fromJson(x))),
from: json["from"],
to: json["to"],
total: json["total"],
);
Map<String, dynamic> toJson() => {
"objects": List<dynamic>.from(objects.map((x) => x.toJson())),
"from": from,
"to": to,
"total": total,
};
}
class Object {
String id;
String name;
String type;
Object({
this.id,
this.name,
this.type,
});
factory Object.fromJson(Map<String, dynamic> json) => Object(
id: json["id"],
name: json["name"],
type: json["type"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"type": type,
};
}
后来是我定义下拉列表的主类:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dummy.dart';
main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_UploadImageState createState() => _UploadImageState();
}
class _UploadImageState extends State<MyApp> {
bool _isLoading = false;
List<Object> objectList = List();
Future<String> loadFromAssets() async {
return await rootBundle.loadString('json/parse.json');
}
@override
void initState() {
// TODO: implement initState
super.initState();
loadYourData();
}
loadYourData() async {
setState(() {
_isLoading = true;
});
String jsonString = await loadFromAssets();
final fruitResponse = fruitResponseFromJson(jsonString);
objectList = fruitResponse.objects;
setState(() {
_isLoading = true;
});
}
@override
Widget build(BuildContext context) {
String selectedFruit;
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: Container(
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5.0),
border: Border.all(
color: Colors.red, style: BorderStyle.solid, width: 0.80),
),
child: DropdownButton(
value: selectedFruit,
isExpanded: true,
icon: Padding(
padding: const EdgeInsets.only(left: 15.0),
child: Icon(Icons.arrow_drop_down),
),
iconSize: 25,
underline: SizedBox(),
onChanged: (newValue) {
setState(() {
print(newValue);
selectedFruit = newValue;
});
print(selectedFruit);
},
hint: Padding(
padding: const EdgeInsets.all(8.0),
child: Text('Select'),
),
items: objectList.map((data) {
return DropdownMenuItem(
value: data.id.toString(),
child: Padding(
padding: const EdgeInsets.only(left: 10.0),
child: Text(
data.name,
style: TextStyle(
fontSize: 18,
color: Colors.black,
),
),
),
);
}).toList()),
),
),
),
),
),
);
}
}
答案 1 :(得分:0)
我给你个主意,您必须将String更改为Object
将DropdownButton替换为DropdownButton,其中FruitResponse是您要使用的对象。
和
Replace onChanged: (String newValue) {
setState(() {
selectedName = newValue;
});
print(selectedName);
}
到
onChanged: (FruitResponse newValue) {
setState(() {
selectedName = newValue.nameid;
});
print(selectedName);
}
然后将DropdownMenuItem更改为DropdownMenuItem
答案 2 :(得分:0)
例如listaCatalogo.partes是一个对象列表:
List<DropdownMenuItem<Catalogo>> _itemsPartes() {
var provider = Provider.of<CatalogNotifier>(context);
return provider.listaCatalogo.partes
.map((item) => DropdownMenuItem<Catalogo>(
value: item,
child: Text(item.valor),
))
.toList();
}
DropdownButton<Catalogo>(
value: registro.parteCat,
onChanged: (Catalogo value) {
setState(() {
registro.parteCat = value;
registro.parte = value.id;
});
},
items: _itemsPartes(),
)