赞
踩
ArkTS 框架采用 List 容器创建列表(类似 Android 的 RecycleView、Compose 的 LazyColumn)。
使用列表可以轻松高效地显示结构化、可滚动的信息。通过在 List 组件中按垂直或者水平方向线性排列子组件 ListItemGroup 或 ListItem,为列表中的行或列提供单个视图,或使用ForEach 迭代一组行或列,或混合任意数量的单个视图和 ForEach 结构,构建一个列表。
列表作为一种容器,会自动按其滚动方向排列子组件,向列表中添加组件或从列表中移除组件会重新排列子组件。
如下图所示,在垂直列表中,List 按垂直方向自动排列 ListItemGroup 或 ListItem。
ListItemGroup 用于列表数据的分组展示,其子组件也是 ListItem。ListItem 表示单个列表项,可以包含单个子组件。
List的子组件必须是 ListItemGroup 或 ListItem,ListItem 和 ListItemGroup 必须配合 List 来使用。
List 静态地创建其列表项 ListItem 的内容:
@Component struct ListTest { build() { List() { ListItem() { Text("Kotlin").fontSize(10) } ListItem() { Text("TypeScript").fontSize(10) } ListItem() { Text("ArkTS").fontSize(10) } } .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Center) } }
我们可以丰富一下 ListItem,给它加上图标:
@Component struct ListTest { build() { List() { ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("Kotlin").fontSize(10) } } ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("TypeScript").fontSize(10) } } ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("ArkTS").fontSize(10) } } } .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Start) } }
一个列表项这么创建好了,但是我们可以发现 ListItem 内部的代码结构是一模一样的,这样写会显得代码很臃肿。
ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("Kotlin").fontSize(10) } } ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("TypeScript").fontSize(10) } } ListItem() { Row() { Image($r('app.media.icon')).width(20).height(20).margin(10) Text("ArkTS").fontSize(10) } }
ArkTS 通过 ForEach 提供了组件的循环渲染能力。我们可以使用 ForEach,在其中以嵌套 ListItem 的形式来代替多个平铺的、内容相似的 ListItem,从而减少重复代码。如果对于 ForEach 不了解,可以查看 【 写给初学者的 HarmonyOS 教程 – 循环渲染(ForEach)】,了解其用法。
import util from '@ohos.util'; class Language { key: string = util.generateRandomUUID(true); icon: Resource; name: string; constructor(icon: Resource, name: string) { this.icon = icon; this.name = name; } } @Entry @Component struct ListTest { private devLanguages = [ new Language($r("app.media.icon"), 'Kotlin'), new Language($r("app.media.icon"), 'TypeScript'), new Language($r('app.media.icon'), 'ArkTS') ] build() { List() { ForEach(this.devLanguages, (item: Language) => { ListItem() { Row() { Image(item.icon).width(20).height(20).margin(10) Text(item.name).fontSize(10) } .width('100%') .justifyContent(FlexAlign.Start) } }) } .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Start) } }
在初始化列表时,可以使用 space 参数添加列表项的间距。例如,在每个列表项之间沿主轴方向添加 30vp 的间距:
build() {
List({ space: 30 }) {
ForEach(this.devLanguages, (item: Language) => {
... ...
})
}
}
List 提供了divider 属性用于给列表项之间添加分隔线。
List({ space: 30 }) { ForEach(this.devLanguages, (item: Language) => { ListItem() { Row() { Image(item.icon).width(20).height(20).margin(10) Text(item.name).fontSize(10) } .width('100%') .justifyContent(FlexAlign.Start) } }) } .divider({ strokeWidth: 1, // 分割线粗细 startMargin: 40, // 分隔线距离列表侧边起始端的距离 endMargin: 10, // 分隔线距离列表侧边结束端的距离 color: '#ff085DFF' // 分割线颜色 })
效果:
实际 UI 界面可能会有很多列表项,超出屏幕后我们就需要添加滚动条,让用户可以滚动屏幕。比如我们再多添加几个语言:
private devLanguages = [ new Language($r("app.media.icon"), 'Kotlin'), new Language($r("app.media.icon"), 'TypeScript'), new Language($r('app.media.icon'), 'ArkTS'), new Language($r('app.media.icon'), 'Python'), new Language($r('app.media.icon'), 'Java'), new Language($r('app.media.icon'), 'JavaScript'), new Language($r('app.media.icon'), 'C++'), new Language($r('app.media.icon'), 'C#'), new Language($r('app.media.icon'), 'Ruby'), new Language($r('app.media.icon'), 'Swift'), new Language($r('app.media.icon'), 'Go'), new Language($r('app.media.icon'), 'PHP'), new Language($r('app.media.icon'), 'Flutter'), new Language($r('app.media.icon'), 'R'), ]
这个时候一个屏幕塞不下这么多列表项,我们可以通过 List 的 scrollBar 属性控制列表滚动条的显示。
scrollBar 的取值类型为 BarState,当取值为 BarState.Auto 表示按需显示滚动条。此时,当触摸到滚动条区域时显示控件,可上下拖拽滚动条快速浏览内容,拖拽时会变粗。若不进行任何操作,2秒后滚动条自动消失。
List() {
...
}
.scrollBar(BarState.Auto)
效果:
所谓分组列表,就是给列表项分组,比如联系人列表就是分组列表。
在 List 组件中使用 ListItemGroup 对项目进行分组,可以构建二维列表。
在 List 组件中可以直接使用一个或者多个 ListItemGroup 组件,ListItemGroup 的宽度默认充满 List 组件。在初始化ListItemGroup 时,可通过 header 参数设置列表分组的头部组件。
@Component struct ListTest { @Builder itemHead(text: string) { // 列表分组的头部组件 Text(text) .fontSize(10) .backgroundColor('#fff1f3f5') .width('100%') .padding(5) } private devLanguages1 = [ new Language($r("app.media.icon"), 'Kotlin'), new Language($r("app.media.icon"), 'TypeScript'), new Language($r('app.media.icon'), 'ArkTS'), new Language($r('app.media.icon'), 'Python'), ] private devLanguages2 = [ new Language($r('app.media.icon'), 'Java'), new Language($r('app.media.icon'), 'JavaScript'), new Language($r('app.media.icon'), 'C++'), new Language($r('app.media.icon'), 'C#'), ] build() { List() { ListItemGroup( { header: this.itemHead( '开发语言 1')}) { // 循环渲染分组 开发语言 1 的 ListItem ForEach(this.devLanguages1, (item: Language) => { ListItem() { Row() { Image(item.icon).width(20).height(20).margin(10) Text(item.name).fontSize(10) } .width('100%') .justifyContent(FlexAlign.Start) } }) } .divider({ strokeWidth: 1, startMargin: 40, endMargin: 10, color: '#ff085DFF' }) ListItemGroup( { header: this.itemHead( '开发语言 2')}) { // 循环渲染分组 开发语言 2 的 ListItem ForEach(this.devLanguages2, (item: Language) => { ListItem() { Row() { Image(item.icon).width(20).height(20).margin(10) Text(item.name).fontSize(10) } .width('100%') .justifyContent(FlexAlign.Start) } }) } .divider({ strokeWidth: 1, startMargin: 40, endMargin: 10, color: '#ff085DFF' }) } .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Start) } }
效果:
如果多个 ListItemGroup 结构类似,可以将多个分组的数据组成数组,然后使用 ForEach 对多个分组进行循环渲染。
@Component struct ListTest { @Builder itemHead(text: string) { // 列表分组的头部组件 Text(text) .fontSize(10) .backgroundColor('#fff1f3f5') .width('100%') .padding(5) } languagesGroups: object[] = [ { title: '开发语言 1', languages: [ new Language($r("app.media.icon"), 'Kotlin'), new Language($r("app.media.icon"), 'TypeScript'), new Language($r('app.media.icon'), 'ArkTS'), new Language($r('app.media.icon'), 'Python'), ], }, { title: '开发语言 2', languages: [ new Language($r('app.media.icon'), 'Java'), new Language($r('app.media.icon'), 'JavaScript'), new Language($r('app.media.icon'), 'C++'), new Language($r('app.media.icon'), 'C#'), ], } ] build() { List() { // 循环渲染 ListItemGroup,languagesGroups 为多个分组开大语言 languages 和标题 title 的数据集合 ForEach(this.languagesGroups, item => { ListItemGroup({ header: this.itemHead(item.title) }) { // 循环渲染 ListItem ForEach(item.languages, language => { ListItem() { Row() { Image(language.icon).width(20).height(20).margin(10) Text(language.name).fontSize(10) } .width('100%') .justifyContent(FlexAlign.Start) } }) } .divider({ strokeWidth: 1, startMargin: 40, endMargin: 10, color: '#ff085DFF' }) }) } .backgroundColor('#FFF1F3F5') .alignListItem(ListItemAlign.Start) } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。