鴻蒙應用開發之ListContainer

前言

本文主要介紹鴻蒙應用開發中的ListContainer控件的使用,其中涉及如下幾個鴻蒙sdk的知識點。java

  • ListContainer
  • TaskDispatcher
  • EventHandler

咱們廢話很少說,直接進入正題。android

ListContainer

ListContainer等同於Android中的Listview,將會是之後咱們平常開發最常使用的控件之一。爲何說等同於Listview呢?不只是由於效果基本一致,連Api的設計和代碼實現都基本一致,上代碼api

ListItemProvider.javamarkdown

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的佈局文件,不作展開。async

list.xmlide

<?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.javapost

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()建立並返回。 由該分發器分發的全部的任務都是在主線程上按順序執行,它在應用程序結束時被銷燬。

上面的文字都是官方文檔上的,就是想告訴你這些知識點。這裏先不展開,簡單理解,他就是一個任務分發綁定着一個線程池,來幫助應用開發者簡便的完成異步任務。

總結

支持鴻蒙,支持鴻蒙生態。這是真國貨,想交朋友的,你們交個朋友,一塊兒學習進步,寫的很差,請見諒。

相關文章
相關標籤/搜索