简体   繁体   English

如何使用颤振中的列表中的 JSON 数据列表创建 DropdownButton

[英]How to Create DropdownButton with a list of JSON data within a list in flutter

Using the example in How to Create DropdownButton with a list of JSON Data and I want it to populate my DropDownButton in Flutter I have created the following working example:使用如何使用JSON 数据列表创建 DropdownButton 中的示例, 我希望它在 Flutter 中填充我的 DropDownButton我创建了以下工作示例:

main.dart 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']);
  }
}

However, my JSON data will be但是,我的 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}

I have used https://app.quicktype.io/ to generate the following我已使用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,
    };
}

When I replace the class FruitResponse with the updated class FruitResponse and make changes to the items map I get an error.当我用更新的类 FruitResponse 替换类 FruitResponse 并更改项目映射时,我收到一个错误。

Class '_InternalLinkedHashMap' has no instance method 'map' with matching类“_InternalLinkedHashMap”没有匹配的实例方法“map”

Working example in DartPad here https://dartpad.dev/b54d896aa35c159cd1749d5c67db7d52 DartPad 中的工作示例https://dartpad.dev/b54d896aa35c159cd1749d5c67db7d52

Non-working example in DartPad here https://dartpad.dev/0413fb4bb7944ccd378b9eabf4e88ff3 DartPad 中的非工作示例https://dartpad.dev/0413fb4bb7944ccd378b9eabf4e88ff3

I think the problem is just getting the List<Object> names correctly from the json data and using it in the DropDownButton items value.我认为问题只是从 json 数据中正确获取List<Object>名称并在 DropDownButton 项目值中使用它。 I know that map.objects.toString() is not correct, but I don't know what to put there or if I am missing something with _fruitResponse.我知道map.objects.toString()不正确,但我不知道该放什么,或者我是否缺少 _fruitResponse 的某些内容。

Thanks in advance for any help.在此先感谢您的帮助。 I'm struggling with understanding mapping JSON response list data.我正在努力理解映射 JSON 响应列表数据。

Just Check out the following example i have created using the json, i have parsed the json locally :只需查看我使用 json 创建的以下示例,我已在本地解析了 json:

Following is the 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
}

Depending on the json i have created the model class :根据我创建的 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,
    };
}

And later the main class where the i have defined the dropdown :后来我定义了下拉菜单的主类:

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

For example listaCatalogo.partes is a list of Object:例如 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(),
                      )

I give u the idea, you must to change the String to Object我给你的想法,你必须将字符串更改为对象

Replace DropdownButton to DropdownButton Where FruitResponse is the OBject that you want to use.将 DropdownButton 替换为 DropdownButton 其中 FruitResponse 是您要使用的对象。

And

Replace onChanged: (String newValue) {
                    setState(() {
                      selectedName = newValue;
                    });
                    print(selectedName);
                  }

to

onChanged: (FruitResponse newValue) {
                    setState(() {
                      selectedName = newValue.nameid;
                    });
                    print(selectedName);
                  }

And DropdownMenuItem to DropdownMenuItem和 DropdownMenuItem 到 DropdownMenuItem

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM