[经验分享] 用OpenHarmony索引条AlphabetIndexer实现内容分组显示(基于OpenHarmony5.0 release) 原创

深开鸿-孙炼 显示全部楼层 发表于 2024-11-5 16:55:58

前言

索引分类分组是应用中常见的功能,OpenHarmony提供了 索引条(AlphabetIndexer)组件,可以用来实现内容分类过滤。

需求

本文以音乐播放器的歌手列表为例,将歌手名以首字母方式进行分组显示,为用户提供更便捷的查找方法。

image.png

实现

定义索引:

@State alphabetIndexerHead: 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'];

添加组件:

WaterFlow({ scroller: this.scroller }) {
          LazyForEach(this.aAllSingerDataSource, (item: PlayListData, index) => {
            FlowItem() {
              SingerItem({ item })
            }.backgroundColor(Color.White)
            .borderRadius(12)
          })
        }
AlphabetIndexer({ arrayValue: this.alphabetIndexerHead, selected: 0 })
          .autoCollapse(false)
          .itemSize(20)
          .selectedFont({ size: 20 })
          .font({ size: 16 })
          .onSelect((index: number) => {
            if (!this.isLoading) {
              this.updateDataBySelect(this.alphabetIndexerHead[index]);
            }
          })
          .enabled(!this.isLoading)
          .width('10%')

进行数据过滤:

updateDataBySelect(indexer: string) {
    if (indexer === this.currentAlphabet) {
      return;
    }
    this.currentAlphabet = indexer;
    this.aAllSingerDataSource.clear();
    let newData: PlayListData[] = []
    if (indexer === '全') {
      newData = this.totalData;
    } else {
      this.totalData.forEach(aSinger => {
        if (aSinger.indexer === indexer) {
          newData.push(aSinger);
        }
      })
    }
    setTimeout(() => {
      animateTo({ duration: 500 }, () => {
        this.aAllSingerDataSource.setData(newData);
        this.count = this.aAllSingerDataSource.totalCount();
      })
    }, 100)
  }

效果:

image.png

问题

本文使用的是通过数据变更来展示分组的方式,也曾尝试使用其他方式,但都遇到问题:

1、数据不过滤,通过scrollTo的方式滚动到对应歌手首字母索引的位置,在歌手数量较多(>1000)时,经常触发Appfreeze。

2、通过if语句判断当前list的item是否和过滤的索引相同,来控制渲染实现”显示“和”不显示“

1)if(indexer === this.currentAlphabet){FlowItem(){singerItem()}} ,FlowItem渲染时未遍历全量数据,导致内容显示不出来;

2)FlowItem(){if(indexer === this.currentAlphabet){singerItem()}},控制内部Item渲染,还是显示全部Item,其他Item显示为空白。

总结

全量代码工程在集成测试仓的在线音乐场景测试应用

通过开发发现,OpenHarmony组件的显示支持、交互方式还不够完善,渲染逻辑不易理解。

用同样的方法可以实现类似联系人的分组查询等,希望本文能给开发者提供一个参考。

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部