ListContainer列表组件
在实际的App开发中,我们最最最常用的其实就是列表组件。在Android中,它是ListView与recyclerview。在鸿蒙中,它是ListContainer。
下面,我们将详细介绍ListContainer组件的使用方式。
基本用法
在我们创建使用ListContainer组件时,我们一般通过4个步骤进行创建。
创建ListContainer组件
首先,我们需要在XML布局文件定义一个ListContainer组件。示例如下:
<ListContainer ohos:id="$+id:test_listcontainer" ohos:height="match_content" ohos:width="match_parent" ohos:layout_alignment="center"/>
创建数据实体类
第2步,我们需要创建一个实体类模型,用于定义需要使用的列表数据。比如我们资讯类App的实体类有标题,简介,图片等。都可以通过实体类进行定义。
示例如下:
public class MyNews { private String title; private String desc; public MyNews(String title,String desc) { this.title = title; this.desc=desc; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }
这里图片就先省略,只使用标题与描述两个变量。至于图片的获取,我们将在鸿蒙的网络编程章节详细讲解,这里展示跳过。
定义适配器
第3步,我们需要定义适配器。
在鸿蒙中,适配器是继承的BaseItemProvider。你可以把它类比为Android中的Adapter的子类(比如ArrayAdapter等)。示例如下:
public class MyNewsProvider extends BaseItemProvider { private List<MyNews> myNewsList; private AbilitySlice abilitySlice; public MyNewsProvider(List<MyNews> myNewsList,AbilitySlice abilitySlice){ this.myNewsList=myNewsList; this.abilitySlice=abilitySlice; } @Override public int getCount() { return myNewsList == null ? 0 : myNewsList.size(); } @Override public Object getItem(int i) { if (myNewsList != null && i >= 0 && i < myNewsList.size()){ return myNewsList.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(this.abilitySlice).parse(ResourceTable.Layout_list_container_item, null, false); } else { cpt = component; } MyNews myNewsItem = this.myNewsList.get(i); Text title = (Text) cpt.findComponentById(ResourceTable.Id_list_title); title.setText(myNewsItem.getTitle()); Text desc = (Text) cpt.findComponentById(ResourceTable.Id_list_desc); desc.setText(myNewsItem.getDesc()); return cpt; } }
在使用上面的适配器之前,我们还需要定义一个名叫list_container_item的,ListContainer子项的布局文件。list_container_item.xml代码如下:
<?xml version="1.0" encoding="utf-8"?> <DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos" ohos:height="match_parent" ohos:width="match_parent" ohos:orientation="vertical"> <Text ohos:id="$+id:list_title" ohos:height="match_content" ohos:width="match_content" ohos:text_size="30vp" ohos:text_color="#FF0000" ohos:layout_alignment="center"/> <Text ohos:id="$+id:list_desc" ohos:height="match_content" ohos:width="match_content" ohos:text_size="30vp" ohos:text_color="#0000FF" ohos:layout_alignment="center"/> <Image ohos:height="1vp" ohos:width="match_parent" ohos:background_element="#00FF00"/> </DirectionalLayout>
这里,我们定义了2个Text,一个用于显示标题,一个用于显示描述。不过,前面讲解Image组件时并没有讲解到分割线的引用。
其实Image不设置图片,直接设置高度与颜色,是可以创建分割线的。
将数据添加到ListContainer组件
话不多说,最后,我们需要将值赋予ListContainer组件,才算创建成功。代码如下:
public class MainAbilitySlice extends AbilitySlice{ private ListContainer listContainer; @Override public void onStart(Intent intent) { super.onStart(intent); super.setUIContent(ResourceTable.Layout_ability_main); this.listContainer=(ListContainer)findComponentById(ResourceTable.Id_test_listcontainer); List<MyNews> list = getData(); MyNewsProvider myNewsProvider = new MyNewsProvider(list, this); listContainer.setItemProvider(myNewsProvider); } private List<MyNews> getData(){ List<MyNews> myNewsList=new ArrayList<>(); for (int i = 0; i <= 20; i++) { myNewsList.add(new MyNews("Item" + (i),"desc"+(i))); } return myNewsList; } }
运行之后,效果如下所示:
横向ListContainer
在实际的列表中,我们还会使用到横向的列表,比如某些视频App,其横向的视频推荐可以看到很多。那么如果改变ListContainer组件的默认方向呢?
示例代码如下:
this.listContainer.setOrientation(Component.HORIZONTAL);
当然,你也可以直接在XML布局文件中设置orientation属性。效果如下:
需要注意的是,横向的ListView就不要把顶级的宽高设置成match_parent,这样会造成横向屏幕中只有一个子item。应该改为match_content。并且,设置margin边距。不过横向一般没有下划线,可以通过修改子item的布局(list_container_item)进行去除。