自學(xué)HarmonyOS應(yīng)用開發(fā)(70)- 解決ListContainer默認優(yōu)化問題

列表項布局表示問題
使用FileBrowser在目錄之間進行切換時,發(fā)現(xiàn)了一個問題:本來只應(yīng)該在出現(xiàn)在返回上級目錄列表項上面的<<按鈕會按照一定的頻率出現(xiàn)在其他列表項上。具體請參見下面的視頻:
經(jīng)過各種嘗試之后得到的結(jié)論是問題出在下面的代碼:
@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;}
解決方法
這段代碼的邏輯很簡單:如果某一個列表項對應(yīng)的組件已經(jīng)存在就直接使用;否則生成對應(yīng)的新組件。從結(jié)果上看,這個組件并不是系統(tǒng)為每個列表項緩存一個組件,而是為整個ListContainer緩存了若干組件并按照順序分配給列表項。如果每個組件的表示方式都完全相同,這種做法沒有問題;如果像FileBrowser這樣,不同列表項的表示方式不同就會出現(xiàn)下面的問題:

解決的辦法也很簡單:在使用已經(jīng)存在的組件之前進行檢查,看看這個組件是不是該列表項想要的,如果不是就新生成一個:
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說明自己想要什么,我們?yōu)槊總€組件增加了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;}public int getComponentId(){return ResourceTable.Id_parent_layout;}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() {public void onClick(Component component) {listener.changeDir(ParentItem.this.dir);}});}return comp;}
代碼12行中返回的Id_parentlayout需要在布局文件中分別指定。對于ParentItem的布局文件,它的頂層組件的Id在第4行指定:
<DirectionalLayoutxmlns: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"><Textohos: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"/><Buttonohos: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>
經(jīng)過這么一番折騰,軟件的動作如下:
相關(guān)列表項的表示結(jié)果也變成了下面的樣子:

參考資料
ListContainer
https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ui-java-component-listcontainer-0000001060007847
參考代碼
完整代碼可以從以下鏈接下載:
https://github.com/xueweiguo/Harmony/tree/master/FileBrowser
作者著作介紹
《實戰(zhàn)Python設(shè)計模式》是作者去年3月份出版的技術(shù)書籍,該書利用Python 的標準GUI 工具包tkinter,通過可執(zhí)行的示例對23 個設(shè)計模式逐個進行說明。這樣一方面可以使讀者了解真實的軟件開發(fā)工作中每個設(shè)計模式的運用場景和想要解決的問題;另一方面通過對這些問題的解決過程進行說明,讓讀者明白在編寫代碼時如何判斷使用設(shè)計模式的利弊,并合理運用設(shè)計模式。

對設(shè)計模式感興趣而且希望隨學(xué)隨用的讀者通過本書可以快速跨越從理解到運用的門檻;希望學(xué)習(xí)Python GUI 編程的讀者可以將本書中的示例作為設(shè)計和開發(fā)的參考;使用Python 語言進行圖像分析、數(shù)據(jù)處理工作的讀者可以直接以本書中的示例為基礎(chǔ),迅速構(gòu)建自己的系統(tǒng)架構(gòu)。
覺得本文有幫助?請分享給更多人。
關(guān)注微信公眾號【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
