Flutter&OpenHarmony文件夹管理功能实现

前言

文件夹管理是笔记应用中组织内容的基础功能之一。通过文件夹,用户可以将相关的笔记归类存放,形成清晰的层级结构。一个优秀的文件夹管理系统应该支持创建、重命名、删除、移动等基本操作,同时提供直观的树形结构展示。本文将详细介绍如何在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

相关推荐
2401_zq136y0316 小时前
Flutter for OpenHarmony:从零搭建今日资讯App(三十)错误处理与异常管理
flutter
2401_zq136y0317 小时前
Flutter for OpenHarmony:从零搭建今日资讯App(二十六)本地存储实现
flutter
美酒没故事°17 小时前
vue3拖拽+粘贴的综合上传器
前端·javascript·typescript
Dreamboat¿17 小时前
解析PHP安全漏洞:Phar反序列化、Filter链与文件包含的高级利用与防御
android·网络·php
2401_8823515218 小时前
Flutter for OpenHarmony 商城App实战 - 会员中心实现
windows·flutter
周杰伦的稻香19 小时前
MySQL中常见的慢查询与优化
android·数据库·mysql
鸣弦artha19 小时前
Flutter框架跨平台鸿蒙开发——Widget体系概览
flutter·华为·harmonyos
南村群童欺我老无力.19 小时前
Flutter 框架跨平台鸿蒙开发 - 打造安全可靠的密码生成器,支持强度检测与历史记录
flutter·华为·typescript·harmonyos
他们叫我技术总监19 小时前
Python 列表、集合、字典核心区别
android·java·python