Flutter Dart中如何将二维数组转为带标题的Widget?
问题描述
我有一个二维关联数组,想要把它渲染成带标题头的Flutter Widget,但尝试后无法显示标题。
数据示例(转换为Flutter可用的Map结构):
final marks = { "TITLE 1": [ {"image": "https://image.com", "name": "AAAA", "id": 1111}, {"image": "https://image.com", "name": "AAAA", "id": 1111}, ], "TITLE 2": [ {"image": "https://image.com", "name": "AAAA", "id": 1111}, {"image": "https://image.com", "name": "AAAA", "id": 1111}, ], };
期望实现每个标题下方对应横向排列的列表项(分类列表样式)。我之前尝试的代码无法显示标题:
populerplaylist.map((user) => ).toList(),
解决方案
要实现带标题的分类列表,核心是遍历Map的entries(每个entry包含标题key和对应列表value),为每个entry构建标题组件+列表组件的组合。
完整代码示例
import 'package:flutter/material.dart'; class CategoryPlaylist extends StatelessWidget { final Map<String, List<Map<String, dynamic>>> marks = { "TITLE 1": [ {"image": "https://image.com", "name": "AAAA", "id": 1111}, {"image": "https://image.com", "name": "AAAA", "id": 1111}, ], "TITLE 2": [ {"image": "https://image.com", "name": "AAAA", "id": 1111}, {"image": "https://image.com", "name": "AAAA", "id": 1111}, ], }; CategoryPlaylist({super.key}); @override Widget build(BuildContext context) { return ListView.builder( shrinkWrap: true, physics: const BouncingScrollPhysics(), itemCount: marks.length, itemBuilder: (context, index) { // 获取当前分类的标题和列表数据 final category = marks.entries.elementAt(index); final title = category.key; final playlistItems = category.value; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 分类标题 Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), child: Text( title, style: const TextStyle( fontSize: 20, fontWeight: FontWeight.w600, ), ), ), // 横向滚动的列表项 SizedBox( height: 130, child: ListView.builder( scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 12), itemCount: playlistItems.length, itemBuilder: (context, itemIndex) { final item = playlistItems[itemIndex]; return Container( width: 110, margin: const EdgeInsets.only(right: 10), child: Column( children: [ // 封面图片 ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.network( item["image"], height: 90, width: 110, fit: BoxFit.cover, errorBuilder: (context, error, stackTrace) { return Container( height: 90, width: 110, color: Colors.grey[200], child: const Icon(Icons.image_not_supported), ); }, ), ), // 名称文本 const SizedBox(height: 4), Text( item["name"], maxLines: 1, overflow: TextOverflow.ellipsis, style: const TextStyle(fontSize: 14), ), ], ), ); }, ), ), ], ); }, ); } }
关键要点
- 通过
marks.entries遍历Map,同时获取每个分类的标题和对应列表数据,解决之前无法显示标题的问题。 - 外层用垂直
ListView承载多个分类,每个分类内部用横向ListView实现列表项滚动,匹配目标样式。 - 加入了图片加载错误占位、文本溢出处理等细节优化,提升健壮性。
内容的提问来源于stack exchange,提问作者xcodertanks
相关产品推荐
相关产品推荐

