基于映射数据构建Flutter DropdownMenuItem的技术问询
问题:基于API获取的PostListOfDiets列表构建Flutter下拉菜单
现有代码基础
已实现通过API获取数据并映射为PostListOfDiets对象列表的逻辑:
static Future<List<PostListOfDiets>> getPosts() async { SharedPreferences prefs = await SharedPreferences.getInstance(); final token = await prefs.getString('token'); Response response = await get(Uri.parse('some.url'), headers: <String, String>{ 'Accept': 'application/json', 'Authorization': 'Bearer $token', }, ); final List body = json.decode(response.body); return body.map((e) => PostListOfDiets.fromJson(e)).toList(); }
PostListOfDiets实体类定义:
class PostListOfDiets { String? nazwa; String? opis; String? komentarz; String? dietetyk; int? id; PostListOfDiets({this.nazwa, this.opis, this.komentarz, this.dietetyk, this.id}); PostListOfDiets.fromJson(Map<String, dynamic> json) { nazwa = json['nazwa']; opis = json['opis']; komentarz = json['komentarz']; dietetyk = json['dietetyk']; id = json['id']; } }
已编写基础的下拉菜单框架,但测试代码使用模拟数据,需替换为API返回的真实数据:
Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.grey[100], appBar: AppBar( backgroundColor: Colors.grey[900], title: const Text("Some text"), actions: [ IconButton( onPressed: signUserOut, icon: const Icon(Icons.logout), ) ], ), body: Center( child: FutureBuilder<List<PostListOfDiets>>( future: postsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } else if (snapshot.hasData) { return buildPosts(snapshot.data!); } else { return const Text("No data..."); } }, ), ), ); } Widget buildPosts(List<PostListOfDiets> posts) { return Padding( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: DropdownButtonFormField( hint: const Text("Wybierz jadłospis"), items: _products.map((e) => DropdownMenuItem(value: e,child: Text(e),)).toList(), // <- 测试用模拟数据 onChanged: (val) { setState(() { _selectedVal = val as String; }); }, icon: const Icon( Icons.arrow_drop_down_circle, color: Colors.blue, ), dropdownColor: Colors.grey[200], decoration: const InputDecoration( labelText: "Nazwa jadłospis", labelStyle: TextStyle(color: Colors.blue, fontSize: 16.0), prefixIcon: Icon( Icons.list_alt, color: Colors.blue, ), ), ) ); }
解决方案
直接遍历API返回的posts列表,将每个PostListOfDiets对象转换为DropdownMenuItem即可,核心代码替换如下:
items: posts.map((item) { return DropdownMenuItem( value: item.id.toString(), child: Text(item.nazwa.toString()), ); }).toList(),
该方案通过map方法将每个PostListOfDiets对象映射为下拉选项,用id作为选项值,nazwa作为显示文本,完美适配现有数据结构。
内容的提问来源于stack exchange,提问作者bzc0fq
相关产品推荐
相关产品推荐

