• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

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

武飞扬头像
面向对象思考
帮助3

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

演示视频

File类

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

方法名 功能
listRoots 列举文件系统中根目录,Linux系统中只有一个根目录
listFiles 列举指定目录中的所有目录和文件
isDirectory 判断当前文件是否问目录

BrowserItem类

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

学新通

BrowerItem类的代码如下:

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方法:

@Overridepublic 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的实例上:

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方法如下:

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同时传递给这两种列表项。

返回上级目录列表

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

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. 迁移对象目录为空时,设置迁移按钮无效

具体代码如下:

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就简单了:

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 语言进行图像分析、数据处理工作的读者可以直接以本书中的示例为基础,迅速构建自己的系统架构。


觉得本文有帮助?请分享给更多人。

关注微信公众号【面向对象思考】轻松学习每一天!

面向对象开发,面向对象思考!

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhibabfh
系列文章
更多 icon
同类精品
更多 icon
继续加载