You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中点击按钮无法重建fl_chart图表的问题求助

问题分析与修复方案

核心问题原因

  1. 静态Assets读取限制:Flutter通过rootBundle.loadString读取的是打包进应用的Assets文件,debug模式下热重载不会更新Assets内容,修改JSON后必须热重启应用才能读取到新数据。
  2. 冗余的UniqueKey使用:你试图通过更新UniqueKey强制重建图表,但实际上只要dataPoints更新,LineChart会自动根据新生成的LineChartData完成重建,无需额外设置Key。

修复步骤

1. 确保读取最新JSON数据

修改assets/data.json后,不要使用热重载,而是点击IDE的热重启按钮(终端中按r键),之后点击按钮即可加载新数据。若为release模式,需重新打包应用才能更新Assets中的JSON内容。

2. 优化代码(更规范简洁)

移除冗余的chartKey,简化代码逻辑,setState更新dataPoints后,build方法会自动生成新的LineChartData,触发图表重建:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fl_chart/fl_chart.dart';

void main() {
 runApp(const MyApp());
}

class MyApp extends StatelessWidget {
 const MyApp({super.key});

 @override
 Widget build(BuildContext context) {
   return const MaterialApp(
     home: ChartPage(),
   );
 }
}

class ChartPage extends StatefulWidget {
 const ChartPage({super.key});

 @override
 ChartPageState createState() => ChartPageState();
}

class ChartPageState extends State<ChartPage> {
 List<DataPoint> dataPoints = [];

 @override
 void initState() {
   super.initState();
   loadChartData();
 }

 Future<void> loadChartData() async {
   final jsonString = await rootBundle.loadString('assets/data.json');
   final jsonData = json.decode(jsonString);
   List<DataPoint> newDataPoints = [];
   for (var item in jsonData) {
     newDataPoints.add(DataPoint(
       day: item['day'],
       value: item['value'],
     ));
   }
   setState(() {
     dataPoints = newDataPoints;
   });
 }

 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       title: const Text('Chart Example'),
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
           ElevatedButton(
             onPressed: () {
               loadChartData();
             },
             child: const Text('Reload Chart Data'),
           ),
           Expanded(
             child: dataPoints.isNotEmpty
                 ? LineChart(
                     LineChartData(
                       gridData: const FlGridData(show: false),
                       titlesData: const FlTitlesData(show: false),
                       borderData: FlBorderData(show: true),
                       minX: 0,
                       maxX: dataPoints.length.toDouble() - 1,
                       minY: 0,
                       maxY: getMaxYValue(dataPoints),
                       lineBarsData: [
                         LineChartBarData(
                           spots: getDataSpots(dataPoints),
                           isCurved: true,
                           dotData: const FlDotData(show: false),
                         ),
                       ],
                     ),
                   )
                 : const Text('No data available. Press the button to load data.'),
           ),
         ],
       ),
     ),
   );
 }

 List<FlSpot> getDataSpots(List<DataPoint> data) {
   return data
       .asMap()
       .map((index, value) => MapEntry(index.toDouble(), FlSpot(index.toDouble(), value.value.toDouble())))
       .values
       .toList();
 }

 double getMaxYValue(List<DataPoint> data) {
   double maxValue = 0;
   for (var point in data) {
     if (point.value.toDouble() > maxValue) {
       maxValue = point.value.toDouble();
     }
   }
   return maxValue + 10;
 }
}

class DataPoint {
 final String day;
 final int value;
 DataPoint({required this.day, required this.value});
}

3. 额外建议

如果需要无需重新打包就能动态更新JSON数据,可以使用path_provider包将JSON文件存储到设备本地目录,再读取该文件内容,替代Assets读取方式。


内容的提问来源于stack exchange,提问作者Carlos Costa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:25:55