我希望用户在文本字段中输入文本。当用户单击fab时,文本将作为新行(附加)写入文件。我希望我的应用程序读取文件的内容,并在输入文本字段下方的列表视图中将每一行显示为列表项。当用户输入新文本时,该文本应立即显示在列表视图中。
我能够做到将文本写入文件中。但是如何读取文件并显示其内容?我应该使用streambuilder吗?下面是我到目前为止所做的代码:
let foo .. in ..
答案 0 :(得分:0)
File文档中实际显示了将文件作为流读取的示例,但是一旦您完成文件的读取,流就结束了……我认为如果以下情况它不会继续向您发送数据您稍后再写,但是请尝试一下。如果要观察文件的更改,请尝试使用file.watch函数,该函数返回FileSystemEvent的流。监视FileSystemEvent.modify,然后每次获取事件时,您可以调用一个函数来读取文件并重新显示所有内容。
这种设计可能是多余的,因为您可以在init上读取一次文件,并将字符串列表的状态保存在状态变量或状态框架(如Redux)中。由于您正在控制对文件的所有写入操作,除非在写入时出现任何错误,否则您的状态应该是文件中保存的状态,因此反复读取文件毫无意义。这是一个示例类,可以做到这一点:
import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
class ReadFileScreen extends StatefulWidget {
@override
ReadFileScreenState createState() {
return new ReadFileScreenState();
}
}
class ReadFileScreenState extends State<ReadFileScreen> {
final myController = TextEditingController();
final storage = FileStorage();
List<String> lines = [];
@override
void initState() {
super.initState();
_loadFile();
}
//can not make initState() async, so calling this function asynchronously
_loadFile() async {
final String readLines = await storage.readFileAsString();
debugPrint("readLines: $readLines");
setState(() {
lines = readLines.split("\\n"); //Escape the new line
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Testing'),
),
body: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: new TextField(
controller: myController,
decoration: new InputDecoration(
hintText: 'Enter the text',
),
),
),
new Expanded(
child: new ListView.builder(
itemCount: lines.length,
itemBuilder: (context, index) {
return new Text(lines[index]); //Replace with ListTile here
}),
),
],
),
floatingActionButton: new FloatingActionButton(
child: new Icon(Icons.save_alt),
onPressed: () {
final String enteredText = myController.text;
storage.writeFile(enteredText);
myController.clear();
setState(() {
lines.add(enteredText);
});
},
),
);
}
}
class FileStorage {
Future<String> get _localPath async {
final directory = await getTemporaryDirectory();
return directory.path;
}
Future<File> get _localFile async {
final path = await _localPath;
return File('$path/file.txt');
}
Future<String> readFileAsString() async {
String contents = "";
final file = await _localFile;
if (file.existsSync()) { //Must check or error is thrown
debugPrint("File exists");
contents = await file.readAsString();
}
return contents;
}
Future<Null> writeFile(String text) async {
final file = await _localFile;
IOSink sink = file.openWrite(mode: FileMode.APPEND);
sink.add(utf8.encode('$text\n')); //Use newline as the delimiter
await sink.flush();
await sink.close();
}
}