往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)
✏️ 鸿蒙(HarmonyOS)北向开发知识点记录~
✏️ 鸿蒙(OpenHarmony)南向开发保姆级知识点汇总~
✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?
✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~
✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?
✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?
✏️ 记录一场鸿蒙开发岗位面试经历~
✏️ 持续更新中……
在鸿蒙应用开发中,List组件是一个非常重要的元素,它用于展示一系列数据项,非常适合构建列表界面,例如商品列表、联系人列表、消息列表等,可以轻松高效地显示结构化、可滚动的信息。
1. List组件
1.1. List组件基本用法
List(value?:{space?: number | string, initialIndex?: number, scroller?: Scroller})
参数说明:
- space:设置子组件在主轴方向的间隔
- initialIndex:设置List组件初次加载的索引值
- scroller:绑定可滚动组件控制器**Scroller **/ ListScroller
1.2. 常用属性和事件
属性 | 描述 |
---|---|
listDirection(value: Axis) | 设置List组件排列方向,默认值:Axis.Vertical |
divider(value: {分割线样式}) | 设置ListItem分割线样式,默认无分割线(null) |
scrollBar(value: BarState) | 设置滚动条状态,默认值:BarState.Auto |
lanes(value:number,**gutter:**number) | 设置List组件的布局列 或 行数,gutter为列 / 行间距,默认:一列无间距 |
alignListItem(value:ListItemAlign) | 设置List交叉轴方向的布局方式,默认值:ListItemAlign.Center |
sticky(value: StickyStyle) | 需要配合ListItemGroup使用,设置ListItemGroup中header和footer是否吸顶或吸底,默认值:StickyStyle.None |
除支持通用事件和滚动组件通用事件外,常用的事件有:
onScrollIndex(event: (start: number, end: number, center: number) => void)
参数说明:
- start:List组件显示区域内的第一个子组件的索引值
- end:List显示区域内的最后一个子组件的索引值
- center:List显示区域内的中间位置的子组件的索引值
1.3. ListScroller控制器
作用: List组件的滚动控制器,通过它可以控制List组件的滚动
listScroller: ListScroller = new ListScroller()
常用方法有:
- 滚动到指定Index索引,支持设置滑动额外偏移量。
scrollToIndex(value: number, smooth?: boolean, align?: ScrollAlign, options?: ScrollToIndexOptions)
参数说明:
- value:滚动到index索引对应的ListItemGroup元素
- smooth?:可选参数,是否开启动画
- align?:可选参数,滚动到的元素与当前容器的对齐方式
- options?:设置滑动到指定Index的配置项,如额外偏移量。
- 滚动到容器边缘,可滚动到顶部/底部
scrollEdge(value: Edge, options?: ScrollEdgeOptions)
参数说明:
- value:滚动到的边缘位置,类型:**Edge,可选:**Top/Start (顶部/左端) | Bottom/End(底部/右端)
- options?:设置滚动到边缘位置的模式 (ScrollEdgeOptions{velocity: number }设置滚动的速度)
- 滚动到指定的ListItemGroup中指定的ListItem
scrollToItemInGroup(index: number, indexInGroup: number, smooth?: boolean, align?: ScrollAlign): void
参数说明:
- index:要滚动到的目标元素所在当前容器中的索引值
- smooth?:可选参数,是否开启动画
- align?:可选参数,滚动到的元素与当前容器的对齐方式
说明: ListScroller继承自Scroller,具有Scroller的全部方法。
2. 子组件ListItem/ListItemGroup
List组件内部仅支持ListItem、ListItemGroup子组件,ListItemGroup组件内部仅支持ListItem组件。
2.1. ListItemGroup的基本用法
ListItemGroup(options?: ListItemGroupOptions)
ListItemGroupOptions参数说明:
参数名 | 参数类型 | 必填 | 参数描述 |
---|---|---|---|
header | CustomBuilder | 否 | 设置ListItemGroup头部组件 |
footer | CustomBuilder | 否 | 设置ListItemGroup尾部组件 |
space | number | string | 否 |
style | ListItemGroupStyle | 否 | 设置List组件卡片样式 |
2.2. ListItemGroup的常用属性
属性 | 说明 |
---|---|
divider(value: {strokeWidth: Length,color?: ResourceColor,startMargin?: Length,endMargin?: Length} null) | 设置子元素ListItem分割线样式: -strokeWidth: 分割线的线宽 -color: 分割线的颜色,默认值:0x08000000 -startMargin: 分割线与列表侧边起始端的距离,默认值:0 -endMargin: 分割线与列表侧边结束端的距离,默认值:0 |
2.3. ListItem的基本用法
ListItem(value?: ListItemOptions) // { style:ListItemStyle}
**参数说明:**style设置List组件卡片样式。
3. 配合AlphabetIndexer组件
AlphabetIndexer组件可以与List组件联动,用于按逻辑结构快速定位容器显示区域。例如,在城市选择列表中,可以通过AlphabetIndexer实现首字母快速索引和定位。
3.1. AlphabetIndexer的基本使用
作用:可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件,常配合List组件使用。
AlphabetIndexer(value: {arrayValue: Array<string>, selected: number})
参数说明:
- arrayValue:字母索引字符串数组,不可设置为空
- selected:选中项索引值,支持$$双向绑定
3.2. 常用属性和事件
属性 | 描述 |
---|---|
usingPopup(value: boolean) | 设置是否使用提示弹窗,默认值:false不显示 |
popupColor(value: ResourceColor) | 设置提示弹窗文字颜色,默认值:0xFF007DFF |
itemSize(value: string number) | 设置字母索引条字母区域大小,默认值:16 |
popupPosition(value: Position) | 设置弹出窗口相对于索引器的位置,默认值:{x:60,y:48} |
popupTitleBackground(value: ResourceColor) | 设置提示弹窗首个索引项背板颜色,默认值:00FFFFFF |
除支持通用事件外,还支持以下事件:
onSelected(callback: (index: number) => void)
3.3. 配合List组件使用
AlphabetIndexer组件通过监听List组件的onScrollIndex事件来更新其选中状态,同时用户点击索引时,可以通过scrollToIndex方法触发List组件滑动并定位到指定首字母的项 。以下是使用List和ListItem组件,配合AlphabetIndexer的一个示例:
@Entry
@Component
struct ListWithAlphabetIndexer {
listScroller: ListScroller = new ListScroller()
/* AlphabetIndexer选中的索引 */
@State selectedIndex: number = 0
build() {
Column() {
List({scroller: this.listScroller}) {
ForEach(dataArray, (item, index) => {
ListItem() {Text(item)}
})
}
.onScrollIndex((firstIndex,lastIndex,centerIndex) => {
// 更新AlphabetIndexer的选中状态
this.selectedIndex = firstIndex
})
AlphabetIndexer({
arrayValue: ['A', 'B', 'C', ...], // 索引字符数组
selected: $$this.selectedIndex // 当前选中的索引,支持双向绑定
})
.onSelect((index) => {
// 根据选中的索引更新List的滚动位置
this.listScroller.scrollToIndex(index);
})
}
}
}
3.4. 通讯录示例和完整代码:
效果图:
具体代码:
interface ContactContent {
initial: string
nameList: string[]
}
@Entry
@Component
struct Index {
/* 数据源 */
contacts: ContactContent[] = [
{ initial: 'A', nameList: ['阿猫', '阿狗', '阿虎', '阿龙', '阿鹰', '阿狼', '阿豹', '阿狮', '阿象', '阿鲸'] },
{ initial: 'B', nameList: ['白兔', '白鸽', '白鹤', '白鹭', '白狐', '白狼', '白虎', '白鹿', '白蛇', '白马'] },
{ initial: 'C', nameList: ['春花', '春风', '春雨', '春草', '春柳', '春燕', '春莺', '春蝶', '春蓝', '春绿'] },
{ initial: 'D', nameList: ['冬雪', '冬梅', '冬松', '冬竹', '冬云', '冬霜', '冬月', '冬夜', '冬青', '冬红'] },
{ initial: 'E', nameList: ['饿狼', '饿虎', '饿鹰', '饿豹', '饿熊', '饿蛇', '饿鱼', '饿虾', '饿蟹', '饿蚌'] },
{ initial: 'F', nameList: ['飞鸟', '飞鱼', '飞虫', '飞蜂', '飞蝶', '飞蛾', '飞蝉', '飞蝗', '飞鼠', '飞猫'] },
{ initial: 'G', nameList: ['孤狼', '孤鹰', '孤虎', '孤豹', '孤蛇', '孤鲨', '孤鲸', '孤鹿', '孤雁', '孤鸿'] },
{ initial: 'H', nameList: ['海鸥', '海龟', '海豚', '海星', '海马', '海葵', '海参', '海胆', '海螺', '海贝'] },
{ initial: 'I', nameList: ['火焰', '火球', '火箭', '火山', '火车', '火柴', '火把', '火鸟'] },
{ initial: 'J', nameList: ['金鱼', '金狮', '金刚', '金鹿', '金蛇', '金鹰', '金豹', '金虎', '金狐', '金猫'] },
{ initial: 'K', nameList: ['孔雀', '恐龙', '开心', '开怀', '开朗', '开拓', '开口', '开花', '开眼', '开天'] },
{ initial: 'L', nameList: ['老虎', '老鹰', '老鼠', '老狼', '老狗', '老猫', '老熊', '老鹿', '老龟', '老蛇'] },
{ initial: 'M', nameList: ['玫瑰', '牡丹', '梅花', '茉莉', '木兰', '棉花', '蜜蜂', '蚂蚁', '马蜂', '蟒蛇'] },
{ initial: 'N', nameList: ['南山', '南极', '南海', '南京', '南阳', '南风', '南瓜', '南竹', '南花', '南鸟'] },
{
initial: 'O',
nameList: ['熊猫', '欧鹭', '欧洲', '欧阳', '欧文', '欧若拉', '欧米茄', '欧罗巴', '欧菲莉亚', '欧瑞斯']
},
{ initial: 'P', nameList: ['苹果', '葡萄', '琵琶', '枇杷', '菩提', '瓢虫', '瓢泼', '飘零', '飘渺', '飘飘然'] },
{ initial: 'Q', nameList: ['七喜', '强风', '奇迹', '乾坤', '奇才', '晴天', '青竹', '秋水', '轻舞', '清泉'] },
{ initial: 'R', nameList: ['瑞雪', '瑞兽', '瑞光', '瑞云', '瑞彩', '瑞气', '瑞香', '瑞草', '瑞莲', '瑞竹'] },
{ initial: 'S', nameList: ['三羊', '三狗', '三猫', '三鱼', '三角', '三鹿', '三鹰', '三蛇', '三狐', '三豹'] },
{ initial: 'T', nameList: ['太阳', '天空', '田园', '太极', '太湖', '天鹅', '太空', '天使', '坦克', '甜橙'] },
{ initial: 'U', nameList: ['乌鸦', '乌鹊', '乌鱼', '乌龟', '乌云', '乌梅', '乌木', '乌金', '乌黑', '乌青'] },
{ initial: 'V', nameList: ['五虎', '五狼', '五鹰', '五豹', '五熊', '五蛇', '五鲨', '五鲸', '五鹿', '五马'] },
{ initial: 'W', nameList: ['悟空', '微笑', '温暖', '无畏', '温柔', '舞蹈', '问心', '悟道', '未来', '文学'] },
{ initial: 'X', nameList: ['西风', '西洋', '西子', '西施', '西岳', '西湖', '西柚', '西竹', '西花', '西鸟'] },
{ initial: 'Y', nameList: ['夜猫', '夜鹰', '夜莺', '夜空', '夜色', '夜月', '夜影', '夜翼', '夜狐', '夜狼'] },
{ initial: 'Z', nameList: ['珍珠', '紫薇', '紫霞', '紫竹', '紫云', '紫燕', '紫鸢', '紫藤', '紫荆', '紫罗兰'] },
]
/* ListItemGroup的头部自定义构建函数 */
@Builder
getHeader(initial: string) {
Text(initial)
.fontSize(18)
.fontWeight(FontWeight.Bolder)
.margin({ left: 10 })
}
/* AlphabetIndexer选中作用 */
@State index: number = 0
/* list的滚动条控制器 */
scroller: ListScroller = new ListScroller()
/* 生成随机颜色 */
getRandomColor(opacity: number = 1) {
let red = Math.floor(Math.random() * 255)
let green = Math.floor(Math.random() * 255)
let blue = Math.floor(Math.random() * 255)
return `rgba(${red},${green},${blue},${opacity})`
}
build() {
Column({ space: 15 }) {
Stack({ alignContent: Alignment.End }) {
Text('通讯录')
.fontSize(20)
.width('100%')
.textAlign(TextAlign.Center)
.padding(10)
.backgroundColor('#fff')
Image($r('app.media.ic_public_add'))
.fillColor('#ff777777')
.width(24)
.margin({ right: 20 })
}
Stack({ alignContent: Alignment.End }) {
Column() {
Row({ space: 10 }) {
Image($r('app.media.ic_public_search'))
.fillColor('#ff777777')
.width(18)
Text('搜索')
}
.justifyContent(FlexAlign.Center)
.borderRadius(21)
.width('90%')
.height(42)
.backgroundColor('#fff')
List({ space: 10, initialIndex: this.index, scroller: this.scroller }) {
ForEach(this.contacts, (item: ContactContent) => {
ListItemGroup({
header: this.getHeader(item.initial),
}) {
ForEach(item.nameList, (name: string) => {
ListItem() {
Row({ space: 10 }) {
Image($r('app.media.user_01'))
.width(32)
.fillColor('#fff')
.backgroundColor(this.getRandomColor())
.padding(5)
.borderRadius(16)
Text(name)
}
.borderRadius(4)
.width('100%')
.padding(10)
.backgroundColor('#fff')
}
})
}
.divider({
strokeWidth: 1,
color: 'rgba(0,0,0,0.2)',
startMargin: 50,
endMargin: 10
})
})
}
.height('100%')
.width('100%')
.padding(10)
.scrollBar(BarState.Off)
.sticky(StickyStyle.Header)
.onScrollIndex(index => {
this.index = index
})
}
AlphabetIndexer({
selected: $$this.index,
arrayValue: this.contacts.map(item => item.initial)
})
.usingPopup(true)// 开启弹框
.popupColor(Color.Orange)// 弹框中字体颜色
.popupPosition({ x: 20, y: 0 })// 弹框的位置
.itemSize(20)// 每个索引组件的大小
.onSelect(index => {
this.index = index
this.scroller.scrollToIndex(index, true)
})
}
}
.backgroundColor('#f2f4f5')
.width('100%')
.height('100%')
}
}