Csv 试图在未来函数中更新我的状态,在按钮小部件中
因此,我正在开发一个通过本地存储的.csv文件注册营养数据的应用程序。营养数据显示在应用程序的主页上。对于从.csv文件添加到应用程序主页的每一行数据,我都会动态添加一个删除按钮(应用程序中的垃圾桶)。我编写了一些代码,然后从.csv文件中删除相应的数据行,之后我想更新主屏幕,以便显示新的.csv文件内容(该行不再可见)。删除功能似乎可以工作,但是在我按下垃圾桶图标后,页面不会用新数据更新自身。只有当我按下显示“Toevoegen”的按钮重新加载页面并按下“Toevoegen”页面中的“back”按钮返回主页面后,主页面才更新为新的.csv文件 我认为这与异步读取.csv文件的函数有关 这是Csv 试图在未来函数中更新我的状态,在按钮小部件中,csv,flutter,asynchronous,dart,future,Csv,Flutter,Asynchronous,Dart,Future,因此,我正在开发一个通过本地存储的.csv文件注册营养数据的应用程序。营养数据显示在应用程序的主页上。对于从.csv文件添加到应用程序主页的每一行数据,我都会动态添加一个删除按钮(应用程序中的垃圾桶)。我编写了一些代码,然后从.csv文件中删除相应的数据行,之后我想更新主屏幕,以便显示新的.csv文件内容(该行不再可见)。删除功能似乎可以工作,但是在我按下垃圾桶图标后,页面不会用新数据更新自身。只有当我按下显示“Toevoegen”的按钮重新加载页面并按下“Toevoegen”页面中的“back
main.dart
文件的代码:
import 'package:percent_indicator/linear_percent_indicator.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:eifit_dual/utility.dart';
import 'package:eifit_dual/addMeal.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Navigation',
home: EiFit(),
);
}
}
class EiFit extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _EiFitState();
}
}
class _EiFitState extends State<EiFit> {
LinearPercentIndicator _percentageIndicator;
List<Widget> morningContent = [];
List<Widget> afternoonContent = [];
List<Widget> eveningContent = [];
@override
void initState() {
super.initState();
_updatePercentage();
_getCSVContent();
}
void _getCSVContent() async {
final _newCSV = await readCSV();
List<Widget> _morningContent = [];
List<Widget> _afternoonContent = [];
List<Widget> _eveningContent = [];
for (var line in _newCSV) {
if (line[1] == 'ochtend') {
_morningContent.add(Row(
children: [
Text(mealNames[line[0]]),
IconButton(
icon: Icon(Icons.delete),
onPressed: () {
removeLineCSV(line).then((result) {});
},
),
],
));
} else if (line[1] == 'middag') {
_afternoonContent.add(Row(
children: [
Text(mealNames[line[0]]),
IconButton(icon: Icon(Icons.delete))
],
));
} else if (line[1] == 'avond') {
_eveningContent.add(Row(
children: [
Text(mealNames[line[0]]),
IconButton(icon: Icon(Icons.delete))
],
));
}
}
setState(() {
morningContent = _morningContent;
afternoonContent = _afternoonContent;
eveningContent = _eveningContent;
});
}
Future _updatePercentage() async {
final exists = await existsCSV();
double _currentPercentage;
if (exists) {
_currentPercentage = await getCurrentPoints() / 12;
print(_currentPercentage);
} else {
_currentPercentage = 0;
}
setState(() {
_percentageIndicator = LinearPercentIndicator(
width: MediaQuery.of(context).size.width - 30,
animation: true,
lineHeight: 20.0,
animationDuration: 400,
percent: _currentPercentage > 1 ? 1 : _currentPercentage,
center: Text((_currentPercentage * 100).toStringAsFixed(0) + '%'),
linearStrokeCap: LinearStrokeCap.roundAll,
progressColor: Colors.green,
);
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('EiFit'),
),
body: SingleChildScrollView(
child: Column(
children: [
Text(
'Progressie',
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
),
Padding(
padding: EdgeInsets.all(15.0),
child: _percentageIndicator,
),
Divider(
color: Colors.grey,
),
Text(
'Ochtend',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
Column(
children: morningContent,
),
Divider(
color: Colors.grey,
),
Text(
'Middag',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
Column(
children: afternoonContent,
),
Divider(
color: Colors.grey,
),
Text(
'Avond',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
Column(
children: eveningContent,
),
Divider(
color: Colors.grey,
),
],
),
),
floatingActionButton: FloatingActionButton.extended(
label: Text('Toevoegen'),
icon: Icon(Icons.add),
backgroundColor: Colors.green,
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => AddMeal()))
.then((context) {
_updatePercentage();
_getCSVContent();
});
},
),
),
);
}
}
方法\u getCSVContent
调用读取.csv文件的函数。然后,逐行读取.csv文件,并为每行的数据创建一个Row()
小部件,其中包含一个Text()
小部件,其中包含.csv数据。在这个Text()
小部件的旁边,创建了一个IconButton
,一旦按下它就会删除数据
我知道这是很多代码要弄清楚。我真的希望有人能理解这个问题并提出解决方案。谢谢你的阅读
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'package:csv/csv.dart';
import 'package:collection/collection.dart';
Future<String> get localPath async {
final directory = await getApplicationDocumentsDirectory();
return directory.path;
}
Future<File> get localFile async {
final path = await localPath;
return File('$path/nutrition_data.csv');
}
Future<File> writeToCSV(newContent) async {
final file = await localFile;
final path = await localPath;
final exists = await File('$path/nutrition_data.csv').exists();
if (exists) {
String content = await file.readAsString();
print('CONTENT');
print(content);
return file.writeAsString(content + newContent);
} else {
return file.writeAsString(newContent);
}
}
Future<void> clearCSV() async {
final file = await localFile;
final path = await localPath;
final exists = await File('$path/nutrition_data.csv').exists();
if (exists) {
file.writeAsString('');
} else {
print('No such file was found.');
}
}
Future<bool> existsCSV() async {
final path = await localPath;
final exists = await File('$path/nutrition_data.csv').exists();
if (exists) {
return true;
} else {
return false;
}
}
Future<List> readCSV() async {
final path = await localPath;
final csv = File('$path/nutrition_data.csv').openRead();
final fields = await csv
.transform(utf8.decoder)
.transform(new CsvToListConverter())
.toList();
return fields;
}
Future<double> getCurrentPoints() async {
final csvData = await readCSV();
double _total = 0;
for (final row in csvData) {
_total += row[2];
}
return _total;
}
Future<void> removeLineCSV(List deleteLine) async {
Function equal = const ListEquality().equals;
final path = await localPath;
bool lineDeleted = false;
final csv = File('$path/nutrition_data.csv').openRead();
final fields = await csv
.transform(utf8.decoder)
.transform(new CsvToListConverter())
.toList();
clearCSV();
for (var line in fields) {
if (equal(deleteLine, line) && (!lineDeleted)) {
lineDeleted = true;
} else {
writeToCSV(line[0].toString() +
',' +
line[1].toString() +
',' +
line[2].toString() +
'\r\n');
}
}
}
// A Map, to map the encoded names of meals into a presentable format
Map mealNames = {
'melk_yoghurt': 'Melk of yoghurt (1pt)',
'ontbijtgranen': 'Ontbijtgranen (2pt)',
'eiwitvoeding': 'Eiwitvoeding (2pt)',
'brood_zoet': 'Brood, zoet beleg (1pt)',
'brood_hartig': 'Brood, hartig beleg (2pt)',
'kwart_bord': 'Kwart bord, warm (2pt)',
'half_bord': 'Half bord, warm (3pt)',
'heel_bord': 'Heel bord, warm (6pt)',
'tussendoortje_zoet': 'Tussendoortje, zoet (0.5pt)',
'tussendoortje_hartig': 'Tussendoortje, hartig (1pt)'
};