3

ArkUI(TS)声明式开发:列表字母索引导航

 2 years ago
source link: https://os.51cto.com/article/706054.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
ArkUI(TS)声明式开发:列表字母索引导航-51CTO.COM
ArkUI(TS)声明式开发:列表字母索引导航
作者:梁青松 2022-04-08 14:47:11
前段时间SDK版本更新了,看了更新介绍,ArkUI(TS)主要是新增了文本输入组件。更新版本后研究一下,发现有些组件也有所更新和优化。所以就想写这个项目。

c96539c17d55b0e77110808ca7ec70bc6a2ef9.png

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

前段时间SDK版本更新了,看了更新介绍,ArkUI(TS)主要是新增了文本输入组件。更新版本后研究一下,发现有些组件也有所更新和优化。所以就想写这个项目。

本项目界面搭建基于ArkUI中TS扩展的声明式开发范式,关于语法和概念直接看官网官方文档地址:​​基于TS扩展的声明式开发范式1、基于TS扩展的声明式开发范式2​​。

  • 工具版本:DevEco Studio 3.0 Beta2。
  • SDK版本:3.0.0.1(API Version 7 Beta2)。

主要知识点

​列表容器(List):​​本次更新加入了Scroller,可以控制列表的跳转位置。

​循环渲染( ForEach ):​​本次更新修复了index不能使用的问题。

​字母索引条(AlphabetIndexer)​​。

1、字母索引导航到列表对应位置,2、列表滑动时也同步定位到字母索引处。

b114a9f88e01ea7c4d54627324ab78260cbd9f.gif

1、布局主要结构。

// 堆叠容器,方向居右
Stack({ alignContent: Alignment.End }) {
   // 列表布局   
   Column() {
        List() {
          ......
        }
   }.width('100%')
   .height('100%')
       
   // 字母索引导航
   AlphabetIndexer()
}

2、列表数据格式。

[
    { name: '周杰伦', headerWord: 'Z' },
    { name: '林俊杰', headerWord: 'L' },
    { name: '陈奕迅', headerWord: 'C' },
    { name: '薛之谦', headerWord: 'X' },
    ......
]

3、列表布局。

这块需要注意的是,分组效果:相同字母只显示一个就行。

// 列表数据
private listContacts: Array<Contacts> = getContactsList()
// 滚动控制器
private scroller: Scroller = new Scroller()
List({ scroller: this.scroller }) {
  ForEach(this.listContacts, (item: Contacts, index) => {
    ListItem() {
      Column() {
        // 字母布局
        if (index == 0) {
          // 第一个肯定要显示
          this.HeaderWord(item)
        } else {
          // 当前字母和前一个不一样就显示 
          if (item.headerWord != this.listContacts[index-1].headerWord) {
            this.HeaderWord(item)
          }
        }
        // 联系人内容布局
        this.ContactsContentLayout(item)
      }
    }
  }, (item, index) => index.toString())
}

4、字母索引导航。

(1)获取列表中字母和索引的对应的map集合,和列表字母布局显示条件是相同的。

  let mapAlphabetsIndex: Map<string, number> = new Map()
  for (var i = 0; i < list.length; i++) {
    const element = list[i];
    // 第一个肯定要添加到map中
    if (i == 0) {
      mapAlphabetsIndex.set(element.headerWord,i)
    } else {
      // 当前字母和前一个不一样,添加到map中
      if (element.headerWord != list[i-1].headerWord) {
        mapAlphabetsIndex.set(element.headerWord,i)
      }
    }
  }

(2)根据字母索引组件选中回调事件,获取字母对应的索引,进行跳转就行。

private alphabets: string[] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
@State private selectedIndex: number = 0
// 字母索引导航
AlphabetIndexer({ arrayValue: this.alphabets, selected: this.selectedIndex })
  .onSelected((index: number) => {// 选中事件回调
    // 选中的字母
    const alphabet = this.alphabets[index]
    // 查询字母在列表中的索引
    const selectedIndex = this.mapAlphabetsIndex.get(alphabet);
    // 跳转到指定索引位置
    this.scroller.scrollToIndex(selectedIndex)
  }) 

5、列表滑动选中字母。

List({ scroller: this.scroller }) {
      ......   
}
.onScrollIndex((start, end) => {
  // 监听滑动时顶部的索引,查询对应的数据
  const element = this.listContacts[start]
  // 更新选中的字母索引
  this.selectedIndex = this.alphabets.indexOf(element.headerWord)
})

项目加了个汉字转拼音的工具类。

https://gitee.com/liangdidi/AlphabetIndexerDemo.git(需要登录才能看到演示图)

此项目经典的使用场景就是联系人,实现过程需要注意:

  • 数据源使用拼音工具类获取大写首字母,并进行列表排序。
  • 字母布局的显示条件,相同字母只显示一个。
  • 首字母与其索引初始化时存入map中,AlphabetIndexer组件在onSelected回调中获取字母对应的索引,滑动到指定的列表位置。
  • List组件在onScrollIndex回调中监听滑动到当前顶部的索引,更新选中的字母索引。

每天进步一点点、需要付出努力亿点点。

​想了解更多内容,请访问:​

​51CTO和华为官方合作共建的鸿蒙技术社区​

​https://ost.51cto.com​

71eea7105a1cf9982d2996c42d853b97bd50ef.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK