前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学HarmonyOS应用开发(69)- 获取并表示手机目录结构

自学HarmonyOS应用开发(69)- 获取并表示手机目录结构

作者头像
面向对象思考
发布2021-09-24 15:42:10
5570
发布2021-09-24 15:42:10
举报

和文件存储比较起来,一般用户更关心的是文件系统的目录结构。本文介绍获取和表示目录结构的方法。先看演示视频:

File类

这是一个Java中的标准类,提供跨平台的文件访问功能。本文主要使用文件类的下面几个功能:

方法名

功能

listRoots

列举文件系统中根目录,Linux系统中只有一个根目录

listFiles

列举指定目录中的所有目录和文件

isDirectory

判断当前文件是否问目录

BrowserItem类

目录项的基类,功能是封装下图中每个目录项的功能。

BrowerItem类的代码如下:

代码语言:javascript
复制
代码语言:javascript
复制
public abstract class BrowserItem {
    interface ItemListener{
        public void changeDir(File dir);
    }
    String name;
    Context context;
    public BrowserItem(Context context, String name) {
        this.context = context;
        this.name = name;
    }
    //取得项目名
    public String getName() {
        return name;
    }
    //设定项目名
    public void setName(String name) {
        this.name = name;
    }
    //生成项目列表项
    abstract public Component createUiComponent();
    //生成详情表示画面
    abstract public void buildView(ComponentContainer container);
}

这个类的主要功能有:

  1. 定义了一个接受项目选择状态变化的ItemListener类
  2. 实现了getName和setName方法
  3. 定义了生成列表项组件的接口createUiComponent。
  4. 定义了生成项目详细信息表示画面的接口buildView。

生成目录项表示组件

BrowerItemProvider为目录项生成表示组件时会调用createUIComponent方法:

代码语言:javascript
复制
代码语言:javascript
复制
@Override
public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
    BrowserItem item = list.get(i);
    final Component cpt;
    if (component == null) {
        cpt = item.createUiComponent();
    } else {
        cpt = component;
    }
    Text text = (Text) cpt.findComponentById(ResourceTable.Id_item_name);
    text.setText(item.getName());
    return cpt;
}

切换当前目录

在FileListContainer构建BrowserItemProvider时,会同时构建一个ItemListener并登录到BrowserItemProvider的实例上:

代码语言:javascript
复制
代码语言:javascript
复制
public FileListContainer(Context context, AttrSet attrSet) {
    super(context, attrSet);
    //...
    sampleItemProvider = new BrowserItemProvider(context, new BrowserItem.ItemListener() {
        @Override
        public void changeDir(File dir) {
            setSelectedItemIndex(-1);
            sampleItemProvider.setCurrentDir(dir);
            setItemProvider(sampleItemProvider);
        }
    });
    setItemProvider(sampleItemProvider);
    setItemSelectedListener(itemSelectedListener);
}

ItemListener收到当前目录切换的通知之后会进行以下处理:

  1. 清除FileListContainer的选择状态
  2. 指定BrowserItemProvider当前目录
  3. 为FileListContainer重新设置BroswerItemProvider以更新ListContainer的内容。

BroswerItemProvider的setCurrnetDir方法如下:

代码语言:javascript
复制
代码语言:javascript
复制
public void setCurrentDir(File dir) {
    list.clear();
    File[] files = dir.listFiles();
    if(files != null) {
        if(dir.getParent() != null){
            list.add(new ParentItem(context, dir.getParentFile(), itemListener));
        }
        for (File file : files) {
            if (file.isDirectory()) {
                list.add(new DirItem(context, file, itemListener));
            } else {
                list.add(new FileItem(context, file));
            }
        }
    }
}

代码取得当前目录的子项目之后,分别构建返回上级目录项目,目录项目和文件项目。在构建返回上级目录项目和目录项目时会将ListContainer生成的ItemListener同时传递给这两种列表项。

返回上级目录列表项

当用户进入某一级目录后,最上面的列表项是返回上级目录项。点击它右侧的<<按钮,可以切换回上级目录。

代码语言:javascript
复制
代码语言:javascript
复制
public class ParentItem extends BrowserItem {
    File dir = null;
    ItemListener listener = null;
    public ParentItem(Context context, File dir, ItemListener listener) {
        super(context, dir.toString());
        this.dir = dir;
        this.listener = listener;
    }
    @Override
    public Component createUiComponent(){
        Component comp =  LayoutScatter.getInstance(context).parse(ResourceTable.Layout_parent_item, null, false);
        Button back = (Button) comp.findComponentById(ResourceTable.Id_extend);
        if(listener != null && dir.listFiles() != null){
            back.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    listener.changeDir(ParentItem.this.dir);
                }
            });
        }
        return comp;
    }
}

createUiComponent在构建表示组件时,为[<<]组件指定了onClick方法。在这个方法中会调用listener对象的changeDir方法,而这个changeDir就是FileListContainer构建BrowserItemProvider时指定的那个。

DirItem

目录列表项和ParentItem的不同之处有:

  1. 使用了不同的布局
  2. 点击右侧[>>时向下级目录迁移
  3. 迁移对象目录为空时,设置迁移按钮无效

具体代码如下:

代码语言:javascript
复制
public class DirItem extends BrowserItem {
    File dir = null;
    ItemListener listener = null;
    public DirItem(Context context, File dir, ItemListener listener) {
        super(context, dir.toString());
        this.dir = dir;
        this.listener = listener;
    }

    @Override
    public Component createUiComponent(){
        Component comp =  LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dir_item, null, false);
        Button extend = (Button) comp.findComponentById(ResourceTable.Id_extend);
        if(listener != null && dir.listFiles() != null){
            extend.setClickedListener(new Component.ClickedListener() {
                @Override
                public void onClick(Component component) {
                    listener.changeDir(DirItem.this.dir);
                }
            });
        }else{
            extend.setTextColor(Color.LTGRAY);
        }
        return comp;
    }
}

FileItem

表示单个文件列表项的FileItem就简单了:

代码语言:javascript
复制
代码语言:javascript
复制
public class FileItem extends BrowserItem {
    File file = null;
    public FileItem(Context context, File file) {
        super(context, file.getName());
        this.file = file;
    }
    @Override
    public Component createUiComponent(){
        return LayoutScatter.getInstance(context).parse(ResourceTable.Layout_file_item, null, false);
    }
}

用户选择目录时更新详细信息表示画面的内容请参照前一篇文章,本文不再重复说明

参考资料

File

https://developer.harmonyos.com/cn/docs/documentation/doc-references/file-0000001054119759

ListContainer

https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-listcontainer-0000001060007847

FileSystems

https://developer.harmonyos.com/cn/docs/documentation/doc-references/filesystems-0000001054238505

FileSystem

https://developer.harmonyos.com/cn/docs/documentation/doc-references/filesystem-0000001054558507

参考代码

完整代码可以从以下链接下载:

https://github.com/xueweiguo/Harmony/tree/master/FileBrowser

作者著作介绍

《实战Python设计模式》是作者去年3月份出版的技术书籍,该书利用Python 的标准GUI 工具包tkinter,通过可执行的示例对23 个设计模式逐个进行说明。这样一方面可以使读者了解真实的软件开发工作中每个设计模式的运用场景和想要解决的问题;另一方面通过对这些问题的解决过程进行说明,让读者明白在编写代码时如何判断使用设计模式的利弊,并合理运用设计模式。

对设计模式感兴趣而且希望随学随用的读者通过本书可以快速跨越从理解到运用的门槛;希望学习Python GUI 编程的读者可以将本书中的示例作为设计和开发的参考;使用Python 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 面向对象思考 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整代码可以从以下链接下载:
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档