Flutter如何从导入CSV生成的隐藏表格中读取单元格值赋值给自定义组件
实现方案
第一步:调整CSV数据加载逻辑
你之前写的RouteNameTable组件仅用于加载CSV且渲染隐藏表格,逻辑冗余,我们可以直接将CSV加载逻辑调整为输出路由数据列表,无需渲染隐藏表格。
首先确认你的CSV结构固定为如下格式即可适配(如果CSV第一行为表头后续可以直接跳过):
| routeNumber | routeName | routeColor |
|---|---|---|
| 33 | Corstorphine - Caversham - City - Wakari | 0xFFF067A6 |
| ... | ... | ... |
第二步:实现数据加载+渲染组件
直接新建一个路由列表组件,加载完CSV后直接生成RouteTemplate列表:
import 'package:flutter/material.dart'; import 'package:csv/csv.dart'; import 'package:flutter/services.dart' show rootBundle; class RouteTemplateList extends StatefulWidget { const RouteTemplateList({Key? key}) : super(key: key); @override State<RouteTemplateList> createState() => _RouteTemplateListState(); } class _RouteTemplateListState extends State<RouteTemplateList> { List<List<dynamic>> _csvData = []; bool _isLoading = true; @override void initState() { super.initState(); _loadCsvData(); } // 加载CSV数据 Future<void> _loadCsvData() async { final csvString = await rootBundle.loadString("assets/routes.csv"); final csvTable = const CsvToListConverter().convert(csvString); setState(() { _csvData = csvTable; _isLoading = false; }); } // 兼容多种格式的色值转Color方法 Color _parseColor(String colorStr) { // 处理带#前缀的色值 if (colorStr.startsWith('#')) { colorStr = colorStr.replaceFirst('#', '0xFF'); } // 处理不带0x前缀的十六进制色值 else if (!colorStr.startsWith('0x')) { colorStr = '0xFF$colorStr'; } return Color(int.parse(colorStr)); } @override Widget build(BuildContext context) { if (_isLoading) { // 加载中状态可自定义为其他占位UI return const CircularProgressIndicator(); } // 如果CSV没有表头,删除.skip(1)即可从第一行开始读取数据 return Column( children: _csvData.skip(1).map((row) { return RouteTemplate( routeNumber: row[0].toString(), routeName: row[1].toString(), routeColor: _parseColor(row[2].toString()), ); }).toList(), ); } }
第三步:多场景复用优化
如果需要在应用多处使用该CSV数据,可将加载逻辑抽为全局工具类,缓存加载完成的数据避免重复读取Assets:
class CsvRouteLoader { static List<List<dynamic>>? _routeData; static Future<List<List<dynamic>>> loadRouteData() async { if (_routeData != null) return _routeData!; final csvString = await rootBundle.loadString("assets/routes.csv"); _routeData = const CsvToListConverter().convert(csvString); return _routeData!; } }
之后任意位置调用CsvRouteLoader.loadRouteData()即可获取已缓存的CSV数据。
注意事项
- 确保
pubspec.yaml中已经正确注册assets/routes.csv资源 - 可根据实际CSV列顺序调整
row[0]、row[1]、row[2]的索引 - 后续CSV更新后只需替换Assets目录下的文件,无需修改代码即可自动同步数据
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

