更多信息请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com/#zz1.什么是ListContainer?什么是列表容器?一个列表组件,用于呈现连续的多行数据,包含一系列相同类型的列表项。如下图所示:2.ListContainer的架构视图ListContainer的架构视图如下:ListContainer是一个列表,列表项数据由适配器Adapter提供,Adapter充当ListContainer之间的中介&桥梁和数据来源。将数据源中的数据映射到ListContainer中进行展示,ListContainer负责将Adapter提供的数据以列表的形式展示出来。三、ListContainer使用步骤ListContainer使用步骤主要包括:1、创建ListContainer2,创建列表项的布局3、使用POJO类封装数据源中每个列表项对应的数据4、构造数据源5、构造适配器Adapter6,将数据源关联到适配器Adapter7,将适配器Adapter应用到ListContainer4.ListContainer实例运行效果如下图所示:开发步骤如下:1.创建一个ListContainer(ability_main.xml)xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:id="$+id:list_container"ohos:height="match_parent"ohos:width="match_parent"/>2.创建列表项的布局(item.xml)xmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_content"ohos:width="match_parent"ohos:orientation="vertical">ohos:id="$+id:name"ohos:height="50vp"ohos:width="match_parent"ohos:padding="5vp"ohos:auto_font_size="true"ohos:text_alignment="center"/>ohos:height="1vp"ohos:width="match_parent"ohos:background_element="#CCCCCC"/>3.使用POJO类封装数据源(Item.java)中每个列表项对应的数据。POJO类指的是:只包含没有业务逻辑类的属性和对应的getter和setterpublicclassItem{privateStringname;publicItem(Stringname){this.name=name;}publicStringgetName(){returnname;}publicvoidsetName(Stringname){this.name=name;}}4.构造数据源(MainAbilitySlice.java)publicclassMainAbilitySliceextendsAbilitySlice{@OverridepublicvoidonStart(Intentintent){super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);Listlist=getData();}privateListgetData(){Listlist=newArrayList<>();for(inti=1;i<=100;i++){list.add(newItem("Item"+i));}returnlist;}}5.构造适配器Adapter的常用适配器类(MyItemProvider.java)它是RecycleItemProvider。继承该类时,需要重写四个方法:getCount()、getItem()、getItemId()和getComponent()。其中,对于方法getComponent(),当列表项从不可见变为可见时,会自动调用该方法。在该方法中,Adapter将从数据源中获取数据,并将返回的数据封装在一个Component对象中。,以便将对象返回到ListContainer以将数据映射到相应的列表项。publicclassMyItemProviderextendsRecycleItemProvider{privateListlist;privateAbilitySliceslice;publicMyItemProvider(Listlist,AbilitySliceslice){this.list=list;this.slice=slice;}@OverridepublicintgetCount(){returnlist.size();}@OverridepublicObjectgetItem(intposition){returnlist.get(position);}@OverridepubliclonggetItemId(intposition){returnposition;}@OverridepublicComponentgetComponent(intposition,ComponentconvertComponent,ComponentContainercomponentContainer){convertComponent=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item,null,false);Texttext=(Text)convertComponent.findComponentById(ResourceTable.Id_name);text.setText(list.get(position).getName());returnconvertComponent;}}6、将数据源关联到合适的配器适配器(MainAbilitySlice.java)publicclassMainAbilitySliceextendsAbilitySlice{@OverridepublicvoidonStart(Intentintent){......Listlist=getData();MyItemProvidermyItemProvider=newMyItemProvider(list,this);}......}7、将合适的适配器应用到ListContainer(MainAbilitySlice.java)publicclassMainAbilitySliceextendsAbilitySlice{@OverridepublicvoidonStart(Intentintent){...MyItemProvidermyItemProvider=newMyItemProvider(list,this);ListContainerlistContainer=(ListContainer)findComponentById(ResourceTable.Id_list_container);listContainer.setItem;myItem)Provider(...}五、Adapter适配优化对于上面的第5步,当一个列表项从不可见变为可见时,对于自动调用的方法getComponent(),我们使用列表项的布局文件item.xml创建一个实例listitem性能较差,因为系统缓存了不可见的listitem实例,getComponent()方法中的第二个参数convertComponent可能不为null,当convertComponent不为null时,表示系统传递了某个listitem缓存中的实例。因此,可以在不重新创建列表项实例的情况下重用列表项实例。优化方法如下:publicclassMyItemProviderextendsRecycleItemProvider{...@OverridepublicComponentgetComponent(intposition,ComponentconvertComponent,ComponentContainercomponentContainer){if(convertComponent==null){convertComponent=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout_item)se,null,}Texttext=(Text)convertComponent.findComponentById(ResourceTable.Id_name);text.setText(list.get(position).getName());returnconvertComponent;}}6.上面代码中使用ViewHolder优化Adapter,获取后列表项实例(无论是新建的列表项实例还是从缓存中获取的列表项实例),都需要调用findComponentById()方法获取列表项中的子组件。调用findComponentById()方法比较耗性能,所以最好在新建一个列表项实例时调用findComponentById()方法获取列表项中的所有子组件,并通过ViewHolder将所有子组件绑定到列表项实例。这样在从缓存中获取列表项实例时,无需调用findComponentById()方法,直接获取列表项实例绑定的ViewHolder即可获取所有子组件。优化方法如下:publicclassMyItemProviderextendsRecycleItemProvider{...@OverridepublicComponentgetComponent(intposition,ComponentconvertComponent,ComponentContainercomponentContainer){ViewHolderviewHolder;if(convertComponent==null){convertComponent=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout);viewHolder=newViewHolder();viewHolder.text=(Text)convertComponent.findComponentById(ResourceTable.Id_name);convertComponent.setTag(viewHolder);}else{viewHolder=(ViewHolder)convertComponent.getTag();}viewHolder.text。setText(list.get(position).getName());returnconvertComponent;}classViewHolder{Texttext;}}如果你理解了为什么需要这个优化,相信你会发现,当列表项只有一个子组件时,不需要引入ViewHolder,直接将这个子组件绑定到列表项实例。代码如下:publicclassMyItemProviderextendsRecycleItemProvider{...@OverridepublicComponentgetComponent(intposition,ComponentconvertComponent,ComponentContainercomponentContainer){Texttext;if(convertComponent==null){convertComponent=LayoutScatter.getInstance(slice).parse(ResourceTable.Layout,_itemfalse);text=(Text)convertComponent.findComponentById(ResourceTable.Id_name);convertComponent.setTag(text);}else{text=(Text)convertComponent.getTag();}text.setText(list.get(position).getName());returnconvertComponent;}}示例源码见附件。欢迎订阅我的专栏【鸿蒙图解】:https://harmonyos.51cto.com/column/27?版权归作者及HarmonyOS技术社区所有。如需转载请注明出处,否则将追究法律责任。想了解更多内容请访问:与华为官方共建鸿蒙科技社区https://harmonyos.51cto.com/#zz
