鸿蒙应用开发之ListContainer
前言
本文主要介绍鸿蒙应用开发中的ListContainer控件的使用,其中涉及以下几个鸿蒙sdk的知识点。
- ListContainer
- TaskDispatcher
- EventHandler
我们废话不多说,直接进入正题。
ListContainer
ListContainer等同于Android中的Listview,将会是以后我们日常开发最常使用的控件之一。为什么说等同于Listview呢?不仅是因为效果基本一致,连Api的设计和代码实现都基本一致,上代码
ListItemProvider.java
public class ListItemProvider extends RecycleItemProvider {
private List<String> data;
private Context context;
private LayoutScatter scatter;
public ListItemProvider(Context context, List<String> data) {
this.context = context;
this.data = data;
this.scatter = LayoutScatter.getInstance(context);
}
@Override
public int getCount() {
return data != null ? data.size() : 0;
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public Component getComponent(int i, Component component, ComponentContainer componentContainer) {
System.out.println("ListItemProvider-getComponent-" + i);
ViewHolder viewHolder = null;
if (component == null) {
component = scatter.parse(ResourceTable.Layout_list_item, null, false);
viewHolder = new ViewHolder((ComponentContainer) component);
component.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) component.getTag();
}
viewHolder.left.setText(data.get(i));
viewHolder.right.setText(data.get(i));
return component;
}
static class ViewHolder {
Text left;
Text right;
public ViewHolder(ComponentContainer container) {
left = (Text) container.findComponentById(ResourceTable.Id_left);
right = (Text) container.findComponentById(ResourceTable.Id_right);
}
}
}
这个类的实现是不是似曾相识?不就是Listview的Adapter嘛,当然这和官方的demo写法不一样,但是这么写,android的同学估计一分钟就能理解了。ListContainer基本照搬了Listview的控件设计,包括Listview模版复用特性。
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="horizontal">
<DependentLayout
ohos:width="0"
ohos:height="match_parent"
ohos:weight="1"
ohos:background_element="#ff0000"
>
<Text
ohos:id="$+id:left"
ohos:width="match_content"
ohos:height="match_content"
ohos:text_size="16vp"
ohos:text_color="#ffffff"
ohos:center_in_parent="true"
/>
</DependentLayout>
<DependentLayout
ohos:width="0"
ohos:height="match_parent"
ohos:weight="1"
ohos:background_element="#0000ff"
>
<Text
ohos:id="$+id:right"
ohos:width="match_content"
ohos:height="match_content"
ohos:text_size="26vp"
ohos:text_color="#ffffff"
ohos:center_in_parent="true"
/>
</DependentLayout>
</DirectionalLayout>
‘
这是item的布局文件,不做展开。
list.xml
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:width="match_parent"
ohos:height="match_parent"
ohos:orientation="vertical">
<ListContainer
ohos:id="$+id:list"
ohos:width="match_parent"
ohos:height="match_parent"
/>
</DirectionalLayout>
这是主布局文件,比较简单,就是ListContainer的声明。
MainAbilitySlice.java
public class MainAbilitySlice extends AbilitySlice {
private ListContainer listContainer;
private ListItemProvider itemProvider;
private List<String> data = new ArrayList<>();
//关联子线程
private EventHandler handler = new EventHandler(EventRunner.create(true));
//关联UI线程
private EventHandler handler2 = new EventHandler(EventRunner.current()) {
@Override
protected void processEvent(InnerEvent event) {
super.processEvent(event);
System.out.println("2-" + Thread.currentThread().getName());
if (event.eventId == 0) {
itemProvider.notifyDataChanged();
}
}
};
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_list);
//1.通过id找到控件实例
listContainer = (ListContainer) findComponentById(ResourceTable.Id_list);
//2.创建Provider实例
itemProvider = new ListItemProvider(this, data);
//3.将Provider和ListContainer绑定
listContainer.setItemProvider(itemProvider);
//4.设置item的点击监听
listContainer.setItemClickedListener(new ListContainer.ItemClickedListener() {
@Override
public void onItemClicked(ListContainer listContainer, Component component, int i, long l) {
}
});
//模拟真实的耗时获取数据,再更新UI
//方式1:使用EventHandler完成线程间的通信
handler.postTask(new Runnable() {
@Override
public void run() {
System.out.println("1-" + Thread.currentThread().getName());
List<String> temp = new ArrayList<>();
for (int i = 0; i < 30; i++) {
temp.add("" + (i + 1));
}
data.addAll(temp);
itemProvider.notifyDataChanged();
}
}, 3000);
//方式2:使用EventHandler和TaskDispatcher配合
createParallelTaskDispatcher("123", TaskPriority.DEFAULT).delayDispatch(new Runnable() {
@Override
public void run() {
System.out.println("1-" + Thread.currentThread().getName());
List<String> temp = new ArrayList<>();
for (int i = 0; i < 30; i++) {
temp.add("" + (i + 1));
}
data.addAll(temp);
handler2.sendEvent(0);
}
}, 3000);
}
@Override
public void onActive() {
super.onActive();
}
@Override
public void onForeground(Intent intent) {
super.onForeground(intent);
}
}
MainAbilitySlice相当于Fragment,最终的实现在这里。重要的步骤已经注释了,也基本上是Listview的使用流程。其实到这里,简单的ListContainer已经完成了,我们这里再简单介绍下EventHandler和TaskDispatcher。
EventHandler
EventHandler在官方文档中篇幅不小,从使用角度,它就是android中的handler,当然其背后的原理可能不一样,还没研究过(估计大同小异),但是使用完全可以参照handler,看下我上面的代码,是不是就是handler的写法。详细介绍下次专门写篇介绍。
TaskDispatcher
看到这里,感觉鸿蒙的这些api都和android极其相似,那TaskDispatcher像是android中的什么呢?还真没有它的兄弟,它更像是android中asynctask的替代,但是设计和使用都天差地别。 官方解释:TaskDispatcher是一个任务分发器,它是Ability分发任务的基本接口,隐藏任务所在线程的实现细节。以下是TaskDispatcher的几种实现。
- GlobalTaskDispatcher:全局并发任务分发器,由Ability执行getGlobalTaskDispatcher()获取。适用于任务之间没有联系的情况。一个应用只有一个
- GlobalTaskDispatcher,它在程序结束时才被销毁。
- ParallelTaskDispatcher:并发任务分发器,由Ability执行createParallelTaskDispatcher()创建并返回。与GlobalTaskDispatcher不同的是,ParallelTaskDispatcher不具有全局唯一性,可以创建多个。开发者在创建或销毁dispatcher时,需要持有对应的对象引用 。
- SerialTaskDispatcher:串行任务分发器,由Ability执行createSerialTaskDispatcher()创建并返回。由该分发器分发的所有的任务都是按顺序执行,但是执行这些任务的线程并不是固定的。如果要执行并行任务,应使用ParallelTaskDispatcher或者GlobalTaskDispatcher,而不是创建多个SerialTaskDispatcher。如果任务之间没有依赖,应使用GlobalTaskDispatcher来实现。它的创建和销毁由开发者自己管理,开发者在使用期间需要持有该对象引用。
- SpecTaskDispatcher:专有任务分发器,绑定到专有线程上的任务分发器。目前已有的专有线程是主线程。UITaskDispatcher和MainTaskDispatcher都属于SpecTaskDispatcher。建议使用UITaskDispatcher。
UITaskDispatcher:绑定到应用主线程的专有任务分发器, 由Ability执行getUITaskDispatcher()创建并返回。 由该分发器分发的所有的任务都是在主线程上按顺序执行,它在应用程序结束时被销毁。
上面的文字都是官方文档上的,就是想告诉你这些知识点。这里先不展开,简单理解,他就是一个任务分发绑定着一个线程池,来帮助应用开发者简便的完成异步任务。
总结
支持鸿蒙,支持鸿蒙生态。这是真国货,想交朋友的,大家交个朋友,一起学习进步,写的不好,请见谅。
作者:暗影萨满