一、支持分組列表
在列表中支持數據的分組展示,可以使列表顯示結構清晰,查找方便,從而提高使用效率。分組列表在實際應用中十分常見,如下圖所示聯系人列表。
聯系人分組列表
在List組件中使用ListItemGroup對項目進行分組,可以構建二維列表。
在List組件中可以直接使用一個或者多個ListItemGroup組件,ListItemGroup的寬度默認充滿List組件。在初始化ListItemGroup時,可通過header參數設置列表分組的頭部組件。
@Entry
@Component
struct ContactsList {@Builder itemHead(text: string) {// 列表分組的頭部組件,對應聯系人分組A、B等位置的組件Text(text).fontSize(20).backgroundColor('#fff1f3f5').width('100%').padding(5)}build() {List() {ListItemGroup({ header: this.itemHead('A') }) {// 循環渲染分組A的ListItem}ListItemGroup({ header: this.itemHead('B') }) {// 循環渲染分組B的ListItem}}}
}
如果多個ListItemGroup結構類似,可以將多個分組的數據組成數組,然后使用ForEach對多個分組進行循環渲染。例如在聯系人列表中,將每個分組的聯系人數據contacts和對應分組的標題title數據進行組合,定義為數組contactsGroups。然后在ForEach中對contactsGroups進行循環渲染,即可實現多個分組的聯系人列表。可參考添加粘性標題示例代碼。
二、添加粘性標題
粘性標題是一種常見的標題模式,常用于定位字母列表的頭部元素。如下圖所示,在聯系人列表中滾動A部分時,B部分開始的頭部元素始終處于A的下方。而在開始滾動B部分時,B的頭部會固定在屏幕頂部,直到所有B的項均完成滾動后,才被后面的頭部替代。
粘性標題不僅有助于闡明列表中數據的表示形式和用途,還可以幫助用戶在大量信息中進行數據定位,從而避免用戶在標題所在的表的頂部與感興趣區域之間反復滾動。
粘性標題–聯系人分組列表
List組件的sticky屬性配合ListItemGroup組件使用,用于設置ListItemGroup中的頭部組件是否呈現吸頂效果或者尾部組件是否呈現吸底效果。
通過給List組件設置sticky屬性為StickyStyle.Header,即可實現列表的粘性標題效果。如果需要支持吸底效果,可以通過footer參數初始化ListItemGroup的底部組件,并將sticky屬性設置為StickyStyle.Footer。
三、完整示例代碼
TestContactsList.ets
import { util } from '@kit.ArkTS'class Contact {contactkey: string = util.generateRandomUUID(true);name: string;avatar: Resource;constructor(name: string, avatar: Resource) {this.name = name;this.avatar = avatar;}
}class ContactsGroup {title: string = '';key: string = '';contacts: Array<object> | null = null;
}let contactsGroups: object[] = [{title: 'A',key: util.generateRandomUUID(true),contacts: [new Contact('Andy', $r('app.media.circle')),new Contact('安沃', $r('app.media.circle')),new Contact('昂科1', $r('app.media.circle')),new Contact('昂科2', $r('app.media.circle')),new Contact('昂科3', $r('app.media.circle')),]} as ContactsGroup,{title: 'B',key: util.generateRandomUUID(true),contacts: [new Contact('Ben', $r('app.media.circle')),new Contact('蹦高', $r('app.media.circle')),new Contact('巴掌1', $r('app.media.circle')),new Contact('巴掌2', $r('app.media.circle')),]} as ContactsGroup,{title: 'C',key: util.generateRandomUUID(true),contacts: [new Contact('ChenL', $r('app.media.circle')),new Contact('成才', $r('app.media.circle')),new Contact('程程1', $r('app.media.circle')),new Contact('程程2', $r('app.media.circle')),new Contact('程程3', $r('app.media.circle')),new Contact('程程4', $r('app.media.circle')),]} as ContactsGroup,{title: 'D',key: util.generateRandomUUID(true),contacts: [new Contact('DIba', $r('app.media.circle')),new Contact('迪迪1', $r('app.media.circle')),new Contact('迪迪2', $r('app.media.circle')),new Contact('迪迪3', $r('app.media.circle')),]} as ContactsGroup
]@Component
struct ItemContact {@Prop item: Contactbuild() {Row({ space: 10 }) {Image(this.item.avatar).width('50vp').height('50vp')Text(this.item.name).fontSize(20).fontColor(Color.Black).ellipsisMode(EllipsisMode.END).maxLines(1)}.width('100%').margin({ top: 16, bottom: 10 }).padding({ left: 16 }).alignItems(VerticalAlign.Center).justifyContent(FlexAlign.Start)}
}@Entry
@Component
struct TestContactsList {@State message: string = '分組列表';// 定義分組聯系人數據集合contactsGroups數組@BuilderitemHead(text: string) {// 列表分組的頭部組件,對應聯系人分組A、B等位置的組件Text(text).fontSize(20).backgroundColor('#fff1f3f5').width('100%').padding(5)}build() {Column({ space: 10 }) {Text(this.message).id('TestContactsListHelloWorld').fontSize(20).fontWeight(FontWeight.Bold)List() {ForEach(contactsGroups, (itemGroup: ContactsGroup) => {ListItemGroup({ header: this.itemHead(itemGroup.title) }) {if (itemGroup.contacts) {ForEach(itemGroup.contacts, (contact: Contact) => {ListItem() {ItemContact({ item: contact })}}, (item: Contact) => JSON.stringify(item))}}}, (itemGroup: ContactsGroup) => JSON.stringify(itemGroup))}.sticky(StickyStyle.Header).scrollBar(BarState.Auto)}}
}