前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学HarmonyOS应用开发(70)- 解决ListContainer默认优化问题

自学HarmonyOS应用开发(70)- 解决ListContainer默认优化问题

作者头像
面向对象思考
发布2021-09-24 15:42:32
2790
发布2021-09-24 15:42:32
举报
文章被收录于专栏:C++核心准则原文翻译

列表项布局表示问题

使用FileBrowser在目录之间进行切换时,发现了一个问题:本来只应该在出现在返回上级目录列表项上面的<<按钮会按照一定的频率出现在其他列表项上。具体请参见下面的视频:

经过各种尝试之后得到的结论是问题出在下面的代码:

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

解决方法

这段代码的逻辑很简单:如果某一个列表项对应的组件已经存在就直接使用;否则生成对应的新组件。从结果上看,这个组件并不是系统为每个列表项缓存一个组件,而是为整个ListContainer缓存了若干组件并按照顺序分配给列表项。如果每个组件的表示方式都完全相同,这种做法没有问题;如果像FileBrowser这样,不同列表项的表示方式不同就会出现下面的问题:

解决的办法也很简单:在使用已经存在的组件之前进行检查,看看这个组件是不是该列表项想要的,如果不是就新生成一个:

代码语言:javascript
复制
代码语言:javascript
复制
public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
    HiLog.info(LABEL, "getComponent, i=%{public}d!", i);
    BrowserItem item = list.get(i);
    Component cpt = null;
    if (component == null) {
        cpt = item.createUiComponent();
    } else {
        if(component.getId() == item.getComponentId()) {
            cpt = component;
        }
        else{
            cpt = item.createUiComponent();
        }
    }
    Text text = (Text) cpt.findComponentById(ResourceTable.Id_item_name);
    text.setText(item.getName());
    return cpt;
}

为了向BowerItemProvider说明自己想要什么,我们为每个组件增加了getComponentId方法。例如ParentItem:

代码语言:javascript
复制
代码语言:javascript
复制
public class ParentItem extends BrowserItem {
    static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00106, "ParentItem");
    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 int getComponentId(){
        return ResourceTable.Id_parent_layout;
    }
     @Override
    public Component createUiComponent(){
        HiLog.info(LABEL, "ParentItem.createUiComponent of %{public}s", name);
        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;
    }

代码12行中返回的Id_parentlayout需要在布局文件中分别指定。对于ParentItem的布局文件,它的顶层组件的Id在第4行指定:

代码语言:javascript
复制
代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
    xmlns:ohos="http://schemas.huawei.com/res/ohos"
    ohos:id="$+id:parent_layout"
    ohos:height="match_content"
    ohos:width="match_parent"
    ohos:left_margin="16vp"
    ohos:right_margin="16vp"
    ohos:orientation="horizontal">
    <Text
        ohos:id="$+id:item_name"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:padding="4vp"
        ohos:text="Item0"
        ohos:text_size="20fp"
        ohos:layout_alignment="left"/>
    <Button
        ohos:id="$+id:extend"
        ohos:height="match_content"
        ohos:width="match_content"
        ohos:padding="4vp"
        ohos:text="$string:BackTo"
        ohos:text_size="20fp"
        ohos:layout_alignment="center"/>
</DirectionalLayout>

经过这么一番折腾,软件的动作如下:

相关列表项的表示结果也变成了下面的样子:

参考资料

ListContainer

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

参考代码

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

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

作者著作介绍

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

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

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整代码可以从以下链接下载:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档