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

网友投稿 683 2022-10-13

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

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

列表项布局表示问题

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

​​演示视频​​

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

@Overridepublic 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这样,不同列表项的表示方式不同就会出现下面的问题:

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

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:

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行指定:

上一篇:Resident 一个依赖于swoole编写的:Php常驻进程框架
下一篇:CharmPy是一个通用的并行和分布式编程框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~