天天看點

java list布局_2020征文-手機圖解鴻蒙清單元件ListContainer

java list布局_2020征文-手機圖解鴻蒙清單元件ListContainer

一、什麼是ListContainer

ListContainer是用來呈現連續、多行資料的清單元件,包含一系列相同類型的清單項。如下圖所示:

java list布局_2020征文-手機圖解鴻蒙清單元件ListContainer

二、ListContainer的架構視圖

ListContainer的架構視圖如下所示:

java list布局_2020征文-手機圖解鴻蒙清單元件ListContainer

ListContainer作為清單,其中的清單項資料是由擴充卡Adapter提供的,擴充卡Adapter作為ListContainer和資料源之間的中介&橋梁,将資料源中的資料映射到要展示的ListContainer中,ListContainer負責以清單的形式顯示擴充卡Adapter提供的資料。

三、ListContainer的使用步驟

ListContainer的使用步驟主要包括:

1、建立ListContainer

2、建立清單項的布局

3、使用POJO類封裝資料源中與每個清單項對應的資料

4、構造資料源

5、構造擴充卡Adapter

6、将資料源關聯到擴充卡Adapter

7、将擴充卡Adapter應用到ListContainer

四、ListContainer的使用示例

示例的運作效果如下圖所示:

java list布局_2020征文-手機圖解鴻蒙清單元件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和setter,而沒有業務邏輯的類。

publicclass Item {

private String name;

publicItem(Stringname) {

this.name=name;

}

publicString getName() {

returnname;

}

publicvoid setName(Stringname) {

this.name=name;

}

}

4、構造資料源(MainAbilitySlice.java)

publicclass MainAbilitySlice extends AbilitySlice {

@Override

publicvoid onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(ResourceTable.Layout_ability_main);

List list = getData();

}

private List getData() {

List list = new ArrayList<>();

for(inti = 1; i <= 100; i++) {

list.add(new Item("Item "+ i));

}

returnlist;

}

}

5、構造擴充卡Adapter(MyItemProvider.java)

常用的擴充卡類是RecycleItemProvider,繼承該類時需要重寫四個方法:getCount()、getItem()、getItemId()和getComponent()。其中,對于方法getComponent(),當某個清單項從不可見變為可見時會自動調用該方法,在該方法中擴充卡Adapter會從資料源取資料,并将傳回的資料封裝在一個Component對象中,以便将該對象傳回給ListContainer,進而将資料映射到對應的清單項。

publicclass MyItemProvider extends RecycleItemProvider {

private List list;

private AbilitySlice slice;

publicMyItemProvider(List list, AbilitySlice slice) {

this.list = list;

this.slice = slice;

}

@Override

publicintgetCount() {

returnlist.size();

}

@Override

publicObject getItem(intposition) {

returnlist.get(position);

}

@Override

publiclong getItemId(intposition) {

returnposition;

}

@Override

publicComponent getComponent(intposition, Component convertComponent, ComponentContainer componentContainer) {

convertComponent = LayoutScatter.getInstance(slice)

.parse(ResourceTable.Layout_item, null,false);

Text text = (Text) convertComponent.findComponentById(ResourceTable.Id_name);

text.setText(list.get(position).getName());

returnconvertComponent;

}

}

6、将資料源關聯到擴充卡Adapter(MainAbilitySlice.java)

publicclass MainAbilitySlice extends AbilitySlice {

@Override

publicvoid onStart(Intent intent) {

......

List list = getData();

MyItemProvider myItemProvider = new MyItemProvider(list, this);

}

......

}

7、将擴充卡Adapter應用到ListContainer(MainAbilitySlice.java)

publicclass MainAbilitySlice extends AbilitySlice {

@Override

publicvoid onStart(Intent intent) {

......

MyItemProvider myItemProvider = new MyItemProvider(list, this);

ListContainer listContainer = (ListContainer) findComponentById(ResourceTable.Id_list_container);

listContainer.setItemProvider(myItemProvider);

}

......

}

五、擴充卡Adapter的優化

對于上面的第5步,當某個清單項從不可見變為可見時,對于自動調用的方法getComponent(),我們是根據清單項的布局檔案item.xml建立了一個清單項的執行個體。這樣的做法性能較差。因為系統會對變為不可見的清單項執行個體進行緩存,是以對于方法getComponent()中的第二個參數convertComponent有可能不為null。當convertComponent不為null時,說明系統把緩存中的某個清單項執行個體傳遞過來了,是以,完全可以複用該清單項執行個體,而沒有必要重新建立一個清單項執行個體。優化方式如下:

publicclass MyItemProvider extends RecycleItemProvider {

......

@Override

publicComponent getComponent(intposition, Component convertComponent, ComponentContainer componentContainer) {

if (convertComponent == null) {

convertComponent = LayoutScatter.getInstance(slice)

.parse(ResourceTable.Layout_item, null,false);

}

Text text = (Text) convertComponent.findComponentById(ResourceTable.Id_name);

text.setText(list.get(position).getName());

returnconvertComponent;

}

}

六、使用ViewHolder對擴充卡Adapter做終極優化

在上面的代碼中,得到清單項執行個體後(不管是新建立的清單項執行個體,還是從緩存中獲得的清單項執行個體),都要調用方法findComponentById()以獲得清單項中的子元件。調用方法findComponentById()是比較耗費性能的,是以好的做法是:在新建立清單項執行個體時,就調用方法findComponentById()以獲得清單項中的所有子元件,并且将所有子元件通過ViewHolder綁定到清單項執行個體。這樣,當從緩存中獲得清單項執行個體後,就無需再調用方法findComponentById()了,直接獲得清單項執行個體綁定的ViewHolder就可以得到所有子元件了。優化方式如下:

publicclass MyItemProvider extends RecycleItemProvider {

......

@Override

publicComponent getComponent(intposition, Component convertComponent, ComponentContainer componentContainer) {

ViewHolder viewHolder;

if (convertComponent == null) {

convertComponent = LayoutScatter.getInstance(slice)

.parse(ResourceTable.Layout_item, null,false);

viewHolder = new ViewHolder();

viewHolder.text = (Text) convertComponent.findComponentById(ResourceTable.Id_name);

convertComponent.setTag(viewHolder);

} else{

viewHolder = (ViewHolder) convertComponent.getTag();

}

viewHolder.text.setText(list.get(position).getName());

returnconvertComponent;

}

class ViewHolder {

Text text;

}

}

如果你了解了為什麼要這麼優化,相信你會發現:當清單項中隻有一個子元件時,也可以不引入ViewHolder,而是将這個子元件直接綁定到清單項執行個體。代碼如下所示:

publicclass MyItemProvider extends RecycleItemProvider {

......

@Override

publicComponent getComponent(intposition, Component convertComponent, ComponentContainer componentContainer) {

Text text;

if (convertComponent == null) {

convertComponent = LayoutScatter.getInstance(slice)

.parse(ResourceTable.Layout_item, null,false);

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技術社群共同所有,如需轉載,請注明出處,否則将追究法律責任

【編輯推薦】

【責任編輯:jianghua TEL:(010)68476606】

點贊 0