前言
文件夹管理是笔记应用中组织内容的基础功能之一。通过文件夹,用户可以将相关的笔记归类存放,形成清晰的层级结构。一个优秀的文件夹管理系统应该支持创建、重命名、删除、移动等基本操作,同时提供直观的树形结构展示。本文将详细介绍如何在Flutter和OpenHarmony平台上实现完善的文件夹管理功能,帮助用户更好地组织和管理笔记内容。
Flutter文件夹列表展示
文件夹列表通常以树形结构展示,支持展开和折叠操作。
dart
class FolderItem extends StatefulWidget {
final Folder folder;
final int depth;
const FolderItem({required this.folder, this.depth = 0});
@override
_FolderItemState createState() => _FolderItemState();
}
class _FolderItemState extends State<FolderItem> {
bool _isExpanded = false;
}
文件夹项组件需要维护展开状态,使用StatefulWidget来管理这个状态。depth参数表示文件夹的层级深度,用于计算缩进距离。这种递归的组件设计可以支持任意深度的文件夹嵌套,非常适合展示树形结构的数据。通过_isExpanded状态变量控制子文件夹的显示和隐藏。
dart
Widget build(BuildContext context) {
return Column(
children: [
InkWell(
onTap: () {
if (widget.folder.children.isNotEmpty) {
setState(() => _isExpanded = !_isExpanded);
}
},
child: Padding(
padding: EdgeInsets.only(left: widget.depth * 20.0),
child: Row(
children: [
Icon(
_isExpanded ? Icons.folder_open : Icons.folder,
color: Colors.amber,
),
SizedBox(width: 8),
Text(widget.folder.name),
Spacer(),
if (widget.folder.children.isNotEmpty)
Icon(_isExpanded ? Icons.expand_less : Icons.expand_more),
],
),
),
),
if (_isExpanded)
...widget.folder.children.map((child) => FolderItem(
folder: child,
depth: widget.depth + 1,
)),
],
);
}
文件夹项的构建使用Column包裹当前文件夹和子文件夹列表。padding根据depth计算左侧缩进,形成层级视觉效果。文件夹图标根据展开状态显示不同的样式,展开时显示打开的文件夹图标。如果有子文件夹,右侧显示展开/折叠箭头。当_isExpanded为true时,递归渲染子文件夹列表,每个子文件夹的depth加1,形成递增的缩进效果。
OpenHarmony文件夹展示
typescript
@Component
struct FolderTreeItem {
@Prop folder: FolderData
@Prop depth: number = 0
@State isExpanded: boolean = false
build() {
Column() {
Row() {
Image(this.isExpanded ? $r('app.media.folder_open') : $r('app.media.folder'))
.width(24)
.height(24)
Text(this.folder.name)
.fontSize(14)
.margin({ left: 8 })
Blank()
if (this.folder.children.length > 0) {
Image(this.isExpanded ? $r('app.media.arrow_up') : $r('app.media.arrow_down'))
.width(16)
.height(16)
}
}
.width('100%')
.padding({ left: this.depth * 20, top: 12, bottom: 12, right: 12 })
.onClick(() => {
if (this.folder.children.length > 0) {
this.isExpanded = !this.isExpanded
}
})
}
}
}
OpenHarmony的文件夹项组件使用@Component装饰器定义。@Prop接收父组件传递的数据,@State管理组件内部状态。Row组件水平排列文件夹图标、名称和展开箭头。padding的left值根据depth计算,实现层级缩进效果。Blank组件填充中间空白区域,使箭头图标靠右显示。onClick事件处理点击操作,切换展开状态。
typescript
if (this.isExpanded) {
ForEach(this.folder.children, (child: FolderData) => {
FolderTreeItem({ folder: child, depth: this.depth + 1 })
})
}
子文件夹的渲染使用条件判断和ForEach循环。当isExpanded为true时,遍历children数组递归创建FolderTreeItem组件。每个子组件的depth参数加1,形成递增的缩进层级。这种递归渲染的方式可以支持任意深度的文件夹结构,代码简洁且易于维护。
创建文件夹功能
创建文件夹是文件夹管理的基本操作。
dart
void _showCreateFolderDialog({Folder? parent}) {
final controller = TextEditingController();
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('新建文件夹'),
content: TextField(
controller: controller,
autofocus: true,
decoration: InputDecoration(
hintText: '请输入文件夹名称',
border: OutlineInputBorder(),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('取消'),
),
ElevatedButton(
onPressed: () {
if (controller.text.isNotEmpty) {
_createFolder(controller.text, parent);
Navigator.pop(context);
}
},
child: Text('创建'),
),
],
),
);
}
创建文件夹使用对话框收集用户输入的文件夹名称。autofocus设置为true使输入框自动获取焦点,方便用户直接输入。parent参数指定父文件夹,如果为null则在根目录创建。创建按钮的点击处理中先验证输入不为空,然后调用_createFolder方法执行创建操作,最后关闭对话框。这种交互流程简洁明了,用户可以快速完成文件夹创建。
OpenHarmony创建文件夹
typescript
@CustomDialog
struct CreateFolderDialog {
controller: CustomDialogController
@State folderName: string = ''
onConfirm: (name: string) => void = () => {}
build() {
Column() {
Text('新建文件夹')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 20 })
TextInput({ placeholder: '请输入文件夹名称' })
.width('100%')
.height(40)
.onChange((value: string) => {
this.folderName = value
})
Row() {
Button('取消')
.backgroundColor('#F0F0F0')
.fontColor('#333333')
.onClick(() => {
this.controller.close()
})
Button('创建')
.backgroundColor('#1890FF')
.fontColor('#FFFFFF')
.onClick(() => {
if (this.folderName.length > 0) {
this.onConfirm(this.folderName)
this.controller.close()
}
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceAround)
.margin({ top: 20 })
}
.padding(20)
.width(300)
}
}
OpenHarmony的自定义对话框使用@CustomDialog装饰器。onConfirm是一个回调函数,用于将用户输入的文件夹名称传递给父组件。TextInput组件收集用户输入,onChange回调实时更新folderName状态。创建按钮的点击处理中验证输入不为空后调用onConfirm回调,然后关闭对话框。按钮使用不同的背景色区分取消和确认操作,提供清晰的视觉引导。
文件夹操作菜单
文件夹的重命名、删除、移动等操作通常通过长按菜单实现。
dart
PopupMenuButton<String>(
onSelected: (value) {
switch (value) {
case 'rename':
_showRenameDialog(folder);
break;
case 'delete':
_showDeleteConfirmDialog(folder);
break;
case 'move':
_showMoveFolderDialog(folder);
break;
}
},
itemBuilder: (context) => [
PopupMenuItem(value: 'rename', child: Text('重命名')),
PopupMenuItem(value: 'delete', child: Text('删除')),
PopupMenuItem(value: 'move', child: Text('移动到...')),
],
)
PopupMenuButton提供了便捷的弹出菜单功能。itemBuilder定义菜单项列表,每个菜单项有一个value用于标识操作类型。onSelected回调根据选择的value执行相应的操作。重命名操作打开重命名对话框,删除操作需要先确认,移动操作打开文件夹选择器。这种设计将多个操作收纳在一个菜单中,保持界面的简洁性。
总结
文件夹管理功能是笔记应用中组织内容的重要工具。通过树形结构展示、创建、重命名、删除、移动等功能的实现,用户可以灵活地组织笔记内容。Flutter和OpenHarmony都提供了构建这些功能所需的基础组件,开发者需要合理设计数据结构和交互流程,为用户提供直观易用的文件夹管理体验。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
