当前位置:网站首页>A Fletter version of Notepad
A Fletter version of Notepad
2022-07-01 13:13:00 【xiangxiongfly915】
a Flutter Version of Notepad
Defining entity classes
class NoteInfo {
final String name;
final String path;
final DateTime updateTime;
const NoteInfo(this.name, this.path, this.updateTime);
}
Home code
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 diary ',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: ' diary '),
);
}
}
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();
},
),
);
}
/// Empty page
_buildEmpty() {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.hourglass_empty_sharp,
color: Colors.black.withOpacity(0.6),
size: 40,
),
Text(
" empty , Come and write a diary ",
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,
);
}
/// Load Journal
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(() {});
}
}
Edit page code
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(" edit "),
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: " Please enter the journal name "),
),
Expanded(
child: TextField(
textAlignVertical: TextAlignVertical.top,
controller: _contentController,
decoration: const InputDecoration(hintText: " Start your story "),
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);
}
}
}
The code download
边栏推荐
- There are still many things to be done in the second half of the year
- Flinkcdc should extract Oracle in real time. What should be configured for oracle?
- Operator-1初识Operator
- [Niu Ke's questions -sql big factory interview real questions] no2 User growth scenario (a certain degree of information flow)
- 请问flink mysql cdc 全量读取mysql某个表数据,对原始的mysql数据库有影响吗
- Function test process in software testing
- Zabbix 6.0 源码安装以及 HA 配置
- 启动solr报错The stack size specified is too small,Specify at least 328k
- shell脚本导入存储过程到数据库
- Class initialization and instantiation
猜你喜欢
Shell script imports stored procedures into the database
游戏公会在去中心化游戏中的未来
【牛客刷题-SQL大厂面试真题】NO2.用户增长场景(某度信息流)
Redis exploration: cache breakdown, cache avalanche, cache penetration
I spent tens of thousands of dollars to learn and bring goods: I earned 3 yuan in three days, and the transaction depends on the bill
Vs code setting Click to open a new file window without overwriting the previous window
MHA high availability cluster deployment and failover of database
[Niu Ke's questions -sql big factory interview real questions] no2 User growth scenario (a certain degree of information flow)
北斗通信模块 北斗gps模块 北斗通信终端DTU
基于mysql乐观锁实现秒杀的示例代码
随机推荐
运行Powershell脚本提示“因为在此系统上禁止运行脚本”解决办法
硬件开发笔记(九): 硬件开发基本流程,制作一个USB转RS232的模块(八):创建asm1117-3.3V封装库并关联原理图元器件
Quickly understand what the compressed list in redis is
学历、长相、家境普通的人,未来的发展方向是什么?00后的职业规划都已经整得明明白白......
flinkcdc要实时抽取oracle,对oracle要配置什么东西?
软件测试中功能测试流程
游戏公会在去中心化游戏中的未来
Three questions about scientific entrepreneurship: timing, pain points and important decisions
codeforces -- 4B. Before an Exam
一款Flutter版的记事本
股票开户要认识谁?实际上网上开户安全么?
MHA high availability cluster deployment and failover of database
There are still many things to be done in the second half of the year
R language uses conf of yardstick package_ The mat function calculates the confusion matrix of the multiclass model on each fold of each cross validation (or resampling), and uses the summary to outpu
[Niu Ke's questions -sql big factory interview real questions] no2 User growth scenario (a certain degree of information flow)
Topic 1004: the story of cows (recursion)
软件测试中功能测试流程
[development of large e-commerce projects] performance pressure test - basic concept of pressure test & jmeter-38
The popular major I chose became "Tiankeng" four years later
Ikvm of toolbox Net project new progress