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

相关推荐
kirk_wang4 小时前
Flutter三方库在OHOS平台适配实践:wakelock屏幕唤醒管理
flutter·移动开发·跨平台·arkts·鸿蒙
颜酱5 小时前
滑动窗口详解:原理+分类+场景+模板+例题(视频贼清晰)
javascript
xq95275 小时前
带你玩转kakao登录 接入教程
android
2501_946233895 小时前
Flutter与OpenHarmony应用设置页面完整开发
android·flutter
橙某人5 小时前
LogicFlow 交互新体验:让锚点"活"起来,鼠标跟随动效实战!🧲
前端·javascript·vue.js
程序猿的程5 小时前
Stock写给前端的股票行情 SDK: stock-sdk,终于不用再求后端帮忙了
前端·javascript·node.js
用户新5 小时前
V8引擎 精品漫游指南 -解析篇 语法解析 AST 作用域 闭包 字节码 优化 一文通关
前端·javascript
2501_944441755 小时前
Flutter&OpenHarmony商城App商品分类导航组件开发
flutter
社恐的下水道蟑螂6 小时前
深入理解 React 中的 Props:组件通信的桥梁
前端·javascript·react.js