当前位置:网站首页>一款Flutter版的记事本
一款Flutter版的记事本
2022-07-01 13:00:00 【xiangxiongfly915】
一款Flutter版的记事本
定义实体类
class NoteInfo {
final String name;
final String path;
final DateTime updateTime;
const NoteInfo(this.name, this.path, this.updateTime);
}
首页代码
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'EditNodePage.dart';
import 'FileUtils.dart';
import 'NoteInfo.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter日记本',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: '日记本'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<NoteInfo> noteList = [];
@override
void initState() {
loadNotes();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: noteList.isEmpty ? _buildEmpty() : _buildList(),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.add, color: Colors.white),
backgroundColor: Colors.blue,
onPressed: () async {
var result = await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return const EditNodePage();
}));
loadNotes();
},
),
);
}
/// 空页面
_buildEmpty() {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.hourglass_empty_sharp,
color: Colors.black.withOpacity(0.6),
size: 40,
),
Text(
"空空如也,快来写日记",
style: TextStyle(color: Colors.black.withOpacity(0.6)),
),
],
),
);
}
_buildList() {
return ListView.separated(
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () async {
var result = await Navigator.of(context).push(MaterialPageRoute(builder: (context) {
return EditNodePage(path: noteList[index].path);
}));
loadNotes();
},
child: ListTile(
title: Text(noteList[index].name),
subtitle: Text("${noteList[index].updateTime}"),
),
);
},
separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
itemCount: noteList.length,
);
}
/// 加载日记
loadNotes() async {
var parentDir = await getTemporaryDirectory();
List<FileSystemEntity> dirList = parentDir.listSync(recursive: false);
List<FileSystemEntity> fileList = [];
for (var dir in dirList) {
if ((await dir.stat()).type == FileSystemEntityType.file) {
fileList.add(dir);
}
}
fileList.sort((f1, f2) {
try {
DateTime dateTime1 = File(f1.path).lastModifiedSync();
DateTime dateTime2 = File(f2.path).lastModifiedSync();
return dateTime2.microsecondsSinceEpoch - dateTime1.microsecondsSinceEpoch;
} catch (e) {
return 0;
}
});
noteList.clear();
for (var f in fileList) {
File file = File(f.path);
if (file.path.endsWith("txt")) {
noteList.add(NoteInfo(FileUtils.getFileName(file.path), file.path, file.lastModifiedSync()));
}
}
setState(() {});
}
}
编辑页代码
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'FileUtils.dart';
class EditNodePage extends StatefulWidget {
final String? path;
const EditNodePage({Key? key, this.path}) : super(key: key);
@override
State<StatefulWidget> createState() {
return _EditNodePageState();
}
}
class _EditNodePageState extends State<EditNodePage> {
late TextEditingController _titleController;
late TextEditingController _contentController;
@override
void initState() {
_titleController = TextEditingController();
_contentController = TextEditingController();
loadData();
super.initState();
}
@override
void dispose() {
_titleController.dispose();
_contentController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("编辑"),
actions: [
IconButton(onPressed: save, icon: const Icon(Icons.done)),
],
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _titleController,
decoration: const InputDecoration(hintText: "请输入日记名称"),
),
Expanded(
child: TextField(
textAlignVertical: TextAlignVertical.top,
controller: _contentController,
decoration: const InputDecoration(hintText: "开始你的故事"),
maxLength: 2000,
maxLines: null,
minLines: 1,
keyboardType: TextInputType.multiline,
),
),
],
),
),
),
);
}
loadData() async {
if (widget.path != null) {
String fileName = FileUtils.getFileName(widget.path);
String content = const Utf8Decoder().convert(await File(widget.path!).readAsBytes());
setState(() {
_titleController.text = fileName;
_contentController.text = content;
});
}
}
save() async {
try {
String title = _titleController.text;
String content = _contentController.text;
var parentDir = await getTemporaryDirectory();
var file = File("${parentDir.path}/$title.txt");
bool exists = file.existsSync();
if (!exists) {
file.createSync();
}
file.writeAsStringSync(content);
Navigator.of(context).pop(title);
} on Exception catch (e) {
print(e);
}
}
}
代码下载
边栏推荐
- 我花上万学带货:3天赚3元,成交靠刷单
- SSO and JWT good article sorting
- 1553B环境搭建
- SVG钻石样式代码
- Based on the open source stream batch integrated data synchronization engine Chunjun data restore DDL parsing module actual combat sharing
- 有没有大佬 遇到过flink监控postgresql数据库, 检查点无法使用的问题
- 数据库之MHA高可用集群部署及故障切换
- 华为HMS Core携手超图为三维GIS注入新动能
- R language builds a binary classification model based on H2O package: using H2O GBM build gradient hoist model GBM, use H2O AUC value of AUC calculation model
- Judea pearl, Turing prize winner: 19 causal inference papers worth reading recently
猜你喜欢
硬件开发笔记(九): 硬件开发基本流程,制作一个USB转RS232的模块(八):创建asm1117-3.3V封装库并关联原理图元器件
Vs code setting Click to open a new file window without overwriting the previous window
波浪动画彩色五角星loader加载js特效
【大型电商项目开发】性能压测-压力测试基本概念&JMeter-38
1553B环境搭建
JS变色的乐高积木
CS5268优势替代AG9321MCQ Typec多合一扩展坞方案
The popular major I chose became "Tiankeng" four years later
Zabbix 6.0 源码安装以及 HA 配置
Operator-1初识Operator
随机推荐
Huawei HMS core joins hands with hypergraph to inject new momentum into 3D GIS
Localtime can't re-enter. It's a pit
Shangtang technology crash: a script written at the time of IPO
Ustime wrote a bug
科学创业三问:关于时机、痛点与重要决策
高薪程序员&面试题精讲系列118之Session共享有哪些方案?
Introduction to reverse debugging PE structure input table output table 05/07
Perl 5.10.0 installation package download
Who should I know when opening a stock account? Is it actually safe to open an account online?
Development trend and market demand analysis report of China's high purity copper industry Ⓕ 2022 ~ 2028
The popular major I chose became "Tiankeng" four years later
ROS2 Foxy depthai_ ROS tutorial
Nc100 converts strings to integers (ATOI)
VM virtual machine configuration dynamic IP and static IP access
R语言基于h2o包构建二分类模型:使用h2o.gbm构建梯度提升机模型GBM、使用h2o.auc计算模型的AUC值
数字化转型再下一城,数字孪生厂商优锘科技宣布完成超3亿元融资
我花上万学带货:3天赚3元,成交靠刷单
leetcode:241. Design priority for operation expression [DFS + Eval]
leetcode:329. 矩阵中的最长递增路径【dfs + cache + 无需回溯 + 优雅】
启动solr报错The stack size specified is too small,Specify at least 328k