前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学HarmonyOS应用开发(68)- 获取并表示文件系统信息

自学HarmonyOS应用开发(68)- 获取并表示文件系统信息

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

接下来我们想通过一个文件浏览器应用,练习文件系统操作,文件表示等功能,本文首先说明获取并表示文件系统内容的方法。还是先看演示视频:

构建FileStore表示画面

首先为准备画面布局:

代码语言:javascript
复制
代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<xwg.filebrowser.DynamicLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:height="match_parent"
    ohos:width="match_parent"
    ohos:background_element="$graphic:main_ability_title_background"
    ohos:orientation="vertical">
    <include
        ohos:id="$id:app_bar"
        ohos:height="match_content"
        ohos:width="match_parent"
        ohos:layout="$layout:app_bar_layout"/>
    <xwg.filebrowser.fileitems.FileListContainer
        ohos:id="$+id:list_container"
        ohos:height="0"
        ohos:weight="300"
        ohos:width="match_parent"
        ohos:layout_alignment="left"/>
    <xwg.filebrowser.LayoutSeparator
        ohos:id="$+id:seperator"
        ohos:height="20vp"
        ohos:width="match_parent"
        ohos:background_element="#7F7F7F"/>
    <DirectionalLayout
        ohos:id="$+id:detail_view_container"
        ohos:width="match_parent"
        ohos:height="0"
        ohos:weight = "300"/>
</xwg.filebrowser.DynamicLayout>

画面的上半部分是一个定制的FileListContainer类,它的功能有:

  1. 获取各个层次的文件系统信息并表示
  2. 当用户选中某个节点时,触发其详细信息的表示

FileListContainer集中管理文件系统节点列表的表示功能。

在构造函数中做了以下几件事:

  1. 设定垂直滚动条格式和有效性
  2. 指定ItemProvider
  3. 指定用于处理选中操作的ListContainer.ItemSelectedListener.
代码语言:javascript
复制
代码语言:javascript
复制
public class FileListContainer extends ListContainer {
    public FileListContainer(Context context, AttrSet attrSet) {
        super(context, attrSet);
        enableScrollBar(Component.AXIS_Y, true);
        setScrollbarThickness(50);
        setScrollbarRoundRect(true);
        setScrollbarRadius(20);
        setScrollbarBackgroundColor(Color.LTGRAY);
        setScrollbarColor(Color.DKGRAY);
        disableFadeEffect(FadeEffectEnum.FADEEFFECT_SCROLLBAR);
        BrowserItemProvider sampleItemProvider = new BrowserItemProvider(context);
        setItemProvider(sampleItemProvider);
        setItemSelectedListener(itemSelectedListener);
    }
    
    public interface SelectedListener{
        public void onItemSelected(FileListContainer listContainer, BrowserItem item);
    }
    SelectedListener selectedListener = null;

    public void setSelectedListener(SelectedListener listener){
        selectedListener = listener;
    }

    ListContainer.ItemSelectedListener itemSelectedListener = new ListContainer.ItemSelectedListener(){
        Component prevSelected = null;
        @Override
        public void onItemSelected(ListContainer listContainer, Component component, int i, long l) {
            if(prevSelected != null){
                FileListContainer.this.setComponentActive(prevSelected, false);
            }
            if(FileListContainer.this.selectedListener != null){
                FileListContainer.this.selectedListener.onItemSelected(FileListContainer.this,
                        (BrowserItem)(FileListContainer.this.getItemProvider().getItem(i)));
            }
            FileListContainer.this.setComponentActive(component, true);
            prevSelected = component;
        }
    };

    void setComponentActive(Component component, boolean active){
        ShapeElement bg = new ShapeElement();
        if(active) {
            bg.setRgbColor(RgbPalette.LIGHT_GRAY);
            bg.setShape(ShapeElement.RECTANGLE);
            component.setBackground(bg);
        }
        else{
            component.setBackground(getBackgroundElement());
        }
    }
}

这个ItemSelectedListener处理选择项目的表示状态之后,将通知转发给自定义的SelectedListener,让开发者可以更简单地处理BrowserItem实例:

代码语言:javascript
复制
public class MainAbilitySlice extends AbilitySlice {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00101, "MainAbilitySlice");
    private ViewCreateHelper viewCreateHelper;

    @Override
    public void onStart(Intent intent) {
        setUIContent(ResourceTable.Layout_browser_ability);
        initListContainer();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    FileListContainer.SelectedListener listener = new FileListContainer.SelectedListener() {
        @Override
        public void onItemSelected(FileListContainer listContainer, BrowserItem item) {
            HiLog.info(LABEL, "MainAbilitySlice.onItemSelected, item=%{public}s!", item.getName());
            ComponentContainer container =
                    (ComponentContainer)(MainAbilitySlice.this.findComponentById(ResourceTable.Id_detail_view_container));
            item.buildView(container);
            container.invalidate();
        }
    };

    private void initListContainer() {
        FileListContainer listContainer = (FileListContainer) findComponentById(ResourceTable.Id_list_container);
        listContainer.setSelectedListener(listener);
    }
}

获取FileStore信息

示例代码中定义了一个BaseItemProvider的派生类为FileListContainer 提供数据,其代码如下:

代码语言:javascript
复制
代码语言:javascript
复制
public class BrowserItemProvider extends BaseItemProvider {
    private List<BrowserItem> list = new ArrayList<>();
    private Context context;
    public BrowserItemProvider(Context c) {
        this.context = c;
        FileSystem fs = FileSystems.getDefault();
        Iterable<FileStore> stores = fs.getFileStores();
        for(FileStore store : stores) {
            list.add(new StoreItem(c, store));
        }
    }
    @Override
    public int getCount() {
        return list == null ? 0 : list.size();
    }
    @Override
    public Object getItem(int i) {
        if (list != null && i >= 0 && i < list.size()){
            return list.get(i);
        }
        return null;
    }
    @Override
    public long getItemId(int i) {
        return i;
    }
    @Override
    public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
        final Component cpt;
        if (component == null) {
            cpt = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dir_item, null, false);
        } else {
            cpt = component;
        }
        BrowserItem item = list.get(i);
        Text text = (Text) cpt.findComponentById(ResourceTable.Id_item_index);
        text.setText(item.getName());
        return cpt;
    }
}  

这些都是使用ListContainer的常规操作。BaseItemProvider和

生成表示信息

目前只是通过FileSystems获取FileStore列表并为每个FileStore实例生成了表示其详细信息的StoreItem。为了将来可以处理更多的数据类型,例如目录,文件等,这个StoreItem类继承自下面的BrowserItem类:

代码语言:javascript
复制
代码语言:javascript
复制
public abstract class BrowserItem {
    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 void buildView(ComponentContainer container);
}

BrowserItem类除了有一个name成员之外,声明了一个纯虚的用于构建详细信息表示视窗的buildView方法。buildView方法接受一个用于管理UI组件的容器组件,设计者可以以为这个组件添加下级组件的方式构建不同类型item的表示画面。

例如StoeItem:

代码语言:javascript
复制
代码语言:javascript
复制
public class StoreItem extends BrowserItem{
    FileStore store;
    public StoreItem(Context context, FileStore s) {
        super(context, s.name());
        store = s;
    }

    @Override
    public void buildView(ComponentContainer container) {
        container.removeAllComponents();
        ComponentContainer child_container = (ComponentContainer)LayoutScatter.getInstance(context).parse(
                ResourceTable.Layout_info_list,
                null,
                false);
        ListContainer list_container = (ListContainer)child_container.findComponentById(
                ResourceTable.Id_info_list_container);
        InfoItemProvider provider = new InfoItemProvider(context);
        try {
            provider.addItem(new SimpleInfoItem("Name", store.name()));
            provider.addItem(new SimpleInfoItem("ReadOnly", String.valueOf(store.isReadOnly())));
            provider.addItem(new SimpleInfoItem("TotalSpace", String.valueOf(store.getTotalSpace()/1024) + " KB"));
            provider.addItem(new SimpleInfoItem("UsableSpace", String.valueOf(store.getUsableSpace()/1024) + " KB"));
            provider.addItem(new SimpleInfoItem("Type", store.type()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        list_container.setItemProvider(provider);
        container.addComponent(child_container);
    }
}

buildView方法首先构建了根据指定的布局文件生成相应的组件,并为其中的ListContainer生成InfoItemProvider示例。接下来从FileStore获取各种信息并作为列表项添加到InfoItemProvider中。最后将生成的整个布局组件添加到通过参数指定的容器中即可。

参考资料

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

FileStore

https://developer.harmonyos.com/cn/docs/documentation/doc-references/filestore-0000001054358485

参考代码

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

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

作者著作介绍

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

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

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

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

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

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

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