Как установить состояние JSON в раскрывающемся поле?

#json #flutter #dart

Вопрос:

 // ignore_for_file: prefer_const_constructors, avoid_unnecessary_containers, prefer_const_literals_to_create_immutables, import_of_legacy_library_into_null_safe, non_constant_identifier_names, unused_field, avoid_print  import 'dart:convert';  import 'package:dropdownfield/dropdownfield.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart';  class FoodWidget extends StatefulWidget {  const FoodWidget({Key? key}) : super(key: key);   @override  _FoodWidgetState createState() =gt; _FoodWidgetState(); }  class _FoodWidgetState extends Statelt;FoodWidgetgt; {  @override  void initState() {  fetchFood();  super.initState();  }   String? food_id;  List food = [];   Futurelt;voidgt; fetchFood() async {  final String response =  await rootBundle.loadString('assets/list_food.json');  final data = await json.decode(response);  print(data);  setState(() {  food = data["food"];  });  }   @override  Widget build(BuildContext context) {  return Container(  padding: EdgeInsets.all(15.0),  child: Column(  crossAxisAlignment: CrossAxisAlignment.stretch,  children: lt;Widgetgt;[  DropDownField(  onValueChanged: (dynamic value) {  food_id = value;  },  value: food_id,  required: false,  labelText: 'Search food',  items: food,  ),  ]),  );  } }  

а это файл JSON. Я хочу, чтобы в раскрывающемся списке были только имена, но я не могу этого сделать. В функции setState я действительно не знаю, как это выразить.

 {  "food": [  {  "id": 1,  "name": "coca-cola",  "calories": 120  },  {  "id": 2,  "name": "egg",  "calories": 80  },  {  "id": 3,  "name": "rice",  "calories": 100  }  ] }  

Я попытался распечатать(данные), чтобы проверить вывод. Все это исходит из доменного имени, но я хочу использовать его внутри. И я действительно не знаю, как это сделать.

пс. Я действительно буду признателен за ответы и предложения.

Ответ №1:

вам просто нужно будет сопоставить данные, чтобы получить только их название :

 Futurelt;voidgt; fetchFood() async {  final String response =  await rootBundle.loadString('assets/list_food.json');  final data = await json.decode(response);  print(data);  setState(() {  food = data["food"].map((e)=gt;e['name']).toList();  });  }   

Там, получив список продуктов, вы сопоставляете каждый элемент, чтобы получить только название продукта, которое вам нужно.

В качестве примечания

Я бы рекомендовал вам в будущем создать такую модель, как :

 class Food {  Food({  this.id,  this.name,  this.calories,  });   int id;  String name;  int calories;   factory Food.fromJson(Maplt;String, dynamicgt; json) =gt; Food(  id: json["id"],  name: json["name"],  calories: json["calories"],  );   Maplt;String, dynamicgt; toJson() =gt; {  "id": id,  "name": name,  "calories": calories,  }; }   

Таким образом, у вас есть строгая типизация Listlt;Foodgt; food , и вы можете получить доступ к параметрам в типобезопасном режиме.

Ответ №2:

Вам нужно создать класс продуктов питания

 class Food {  String? id;  String? name;  String? calories;  Food({  this.id,  this.name,  this.calories,  });   Maplt;String, dynamicgt; toMap() {  return {  'id': id,  'name': name,  'calories': calories,  };  }   factory Food.fromMap(Maplt;String, dynamicgt; map) {  return Food(  id: map['id'],  name: map['name'],  calories: map['calories'],  );  }   String toJson() =gt; json.encode(toMap());   factory Food.fromJson(String source) =gt; Food.fromMap(json.decode(source)); }  

Полный код здесь:

 import 'dart:convert';  import 'package:flutter/material.dart';  import 'package:flutter/services.dart';   class FoodWidget extends StatefulWidget {  const FoodWidget({Key? key}) : super(key: key);   @override _FoodWidgetState createState() =gt; _FoodWidgetState();  }  class _FoodWidgetState extends Statelt;FoodWidgetgt; { @override  void initState() {  fetchFood();  super.initState();  }   String? food_id;  Food? selected_food ;  Listlt;Foodgt; food = [];   Futurelt;voidgt; fetchFood() async {  final String response =  await rootBundle.loadString('assets/list_food.json');  final data = await json.decode(response) as List;  print(data);  setState(() {  food = data.map((e) =gt; Food.fromJson(e)).toList();  });  }   @override  Widget build(BuildContext context) {  return Container(  padding:const EdgeInsets.all(15.0),  child: Column(  crossAxisAlignment: CrossAxisAlignment.stretch,  children: lt;Widgetgt;[  DropdownButtonlt;Foodgt;(  focusColor: Colors.white,  value: selected_food,  //elevation: 5,  style: const TextStyle(color: Colors.white),  iconEnabledColor: Colors.black,  underline: const SizedBox.shrink(),  items: food.maplt;DropdownMenuItemlt;Foodgt;gt;(  (Food value) {  return DropdownMenuItemlt;Foodgt;(  value: value,  child: Text(  value.name!,  style: const TextStyle(color: Colors.black),  ),  );  }).toList(),  hint: const Text(  "Select Shop Category",  style: TextStyle(  color: Colors.black38,  ),  ),  onChanged: (Food? value) {  setState(() {  selected_food= value!;  });  },  ),  ]),  );  }  }   class Food {  String? id;  String? name;  String? calories;  Food({  this.id,  this.name,  this.calories,  });   Maplt;String, dynamicgt; toMap() {  return {  'id': id,  'name': name,  'calories': calories,  };  }   factory Food.fromMap(Maplt;String, dynamicgt; map) {  return Food(  id: map['id'],  name: map['name'],  calories: map['calories'],  );  }   String toJson() =gt; json.encode(toMap());   factory Food.fromJson(String source) =gt;   Food.fromMap(json.decode(source));  }