前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >HarmonyOS 开发实践——List组件的使用与AlphabetIndexer联动实践

HarmonyOS 开发实践——List组件的使用与AlphabetIndexer联动实践

原创
作者头像
小帅聊鸿蒙
发布2024-10-29 20:29:09
发布2024-10-29 20:29:09
5590
举报
文章被收录于专栏:鸿蒙开发笔记鸿蒙开发笔记

在鸿蒙应用开发中,List组件是一个非常重要的元素,它用于展示一系列数据项,非常适合构建列表界面,例如商品列表、联系人列表、消息列表等,可以轻松高效地显示结构化、可滚动的信息。

1. List组件

1.1. List组件基本用法

代码语言:ts
复制
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

除支持通用事件和滚动组件通用事件外,常用的事件有:

代码语言:ts
复制
onScrollIndex(event: (start: number, end: number, center: number) => void)

参数说明:

  • start:List组件显示区域内的第一个子组件的索引值
  • end:List显示区域内的最后一个子组件的索引值
  • center:List显示区域内的中间位置的子组件的索引值

1.3. ListScroller控制器

作用:List组件的滚动控制器,通过它可以控制List组件的滚动

代码语言:ts
复制
listScroller: ListScroller = new ListScroller()

常用方法有:

  1. 滚动到指定Index索引,支持设置滑动额外偏移量。
代码语言:ts
复制
scrollToIndex(value: number, smooth?: boolean, align?: ScrollAlign, options?: ScrollToIndexOptions)

参数说明:

  • value:滚动到index索引对应的ListItemGroup元素
  • smooth?:可选参数,是否开启动画
  • align?:可选参数,滚动到的元素与当前容器的对齐方式
  • options?:设置滑动到指定Index的配置项,如额外偏移量。
  1. 滚动到容器边缘,可滚动到顶部/底部
代码语言:ts
复制
scrollEdge(value: Edge, options?: ScrollEdgeOptions)

参数说明:

  • value:滚动到的边缘位置,类型:Edge,可选:Top/Start (顶部/左端) | Bottom/End(底部/右端)
  • options?:设置滚动到边缘位置的模式 (ScrollEdgeOptions{velocity: number }设置滚动的速度)
  1. 滚动到指定的ListItemGroup中指定的ListItem
代码语言:ts
复制
scrollToItemInGroup(index: number, indexInGroup: number, smooth?: boolean, align?: ScrollAlign): void

参数说明:

  • index:要滚动到的目标元素所在当前容器中的索引值
  • smooth?:可选参数,是否开启动画
  • align?:可选参数,滚动到的元素与当前容器的对齐方式

说明:ListScroller继承自Scroller,具有Scroller的全部方法。

2. 子组件ListItem/ListItemGroup

List组件内部仅支持ListItemListItemGroup子组件,ListItemGroup组件内部仅支持ListItem组件。

2.1. ListItemGroup的基本用法

代码语言:ts
复制
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的基本用法

代码语言:ts
复制
ListItem(value?: ListItemOptions)	// { style:ListItemStyle}

参数说明:style设置List组件卡片样式。

3. 配合AlphabetIndexer组件

AlphabetIndexer组件可以与List组件联动,用于按逻辑结构快速定位容器显示区域。例如,在城市选择列表中,可以通过AlphabetIndexer实现首字母快速索引和定位。

3.1. AlphabetIndexer的基本使用

作用:可以与容器组件联动用于按逻辑结构快速定位容器显示区域的组件,常配合List组件使用。

代码语言:ts
复制
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

除支持通用事件外,还支持以下事件:

代码语言:ts
复制
onSelected(callback: (index: number) => void)

3.3. 配合List组件使用

AlphabetIndexer组件通过监听List组件的onScrollIndex事件来更新其选中状态,同时用户点击索引时,可以通过scrollToIndex方法触发List组件滑动并定位到指定首字母的项 。以下是使用List和ListItem组件,配合AlphabetIndexer的一个示例:

代码语言:ts
复制
@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. 通讯录示例和完整代码:

效果图:

具体代码:

代码语言:ts
复制
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%')
  }
}

写在最后

如果你觉得这篇内容对你还蛮有帮助,我想邀请你帮我三个小忙:

  • 点赞,转发,有你们的 『点赞和评论』,才是我创造的动力;
  • 关注小编,同时可以期待后续文章ing🚀,不定期分享原创知识;
  • 想要获取更多完整鸿蒙最新学习知识点,可关注B站:码牛课堂鸿蒙开发;

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. List组件
    • 1.1. List组件基本用法
    • 1.2. 常用属性和事件
    • 1.3. ListScroller控制器
  • 2. 子组件ListItem/ListItemGroup
    • 2.1. ListItemGroup的基本用法
    • 2.2. ListItemGroup的常用属性
    • 2.3. ListItem的基本用法
  • 3. 配合AlphabetIndexer组件
    • 3.1. AlphabetIndexer的基本使用
    • 3.2. 常用属性和事件
    • 3.3. 配合List组件使用
    • 3.4. 通讯录示例和完整代码:
  • 写在最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档