HarmonyOS 鸿蒙Next中求问,这种样式的侧边索引条是如何实现的呢?
HarmonyOS 鸿蒙Next中求问,这种样式的侧边索引条是如何实现的呢?
我看了AlphabetIndexer()
,在方表盘上显示的内容过多,没有向下箭头显示
而ArcAlphabetIndexer()
适配圆形表盘的
6 回复
可以使用 AlphabetIndexer 进行实现
参考地址
更多关于HarmonyOS 鸿蒙Next中求问,这种样式的侧边索引条是如何实现的呢?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
这个用官方组件AlphabetIndexer来处理的参考文档: AlphabetIndexer-信息展示-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者

代码示例:
// xxx.ets
@Entry
@Component
struct AlphabetIndexerSample {
private arrayA: string[] = ['安'];
private arrayB: string[] = ['卜', '白', '包', '毕', '丙'];
private arrayC: string[] = ['曹', '成', '陈', '催'];
private arrayJ: string[] = ['嘉', '贾'];
private value: 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 isNeedAutoCollapse: boolean = false;
@State indexerHeight: string = '75%';
build() {
Stack({ alignContent: Alignment.Start }) {
Row() {
List({ space: 20, initialIndex: 0 }) {
ForEach(this.arrayA, (item: string) => {
ListItem() {
Text(item)
.width('80%')
.height('5%')
.fontSize(30)
.textAlign(TextAlign.Center)
}
}, (item: string) => item)
ForEach(this.arrayB, (item: string) => {
ListItem() {
Text(item)
.width('80%')
.height('5%')
.fontSize(30)
.textAlign(TextAlign.Center)
}
}, (item: string) => item)
ForEach(this.arrayC, (item: string) => {
ListItem() {
Text(item)
.width('80%')
.height('5%')
.fontSize(30)
.textAlign(TextAlign.Center)
}
}, (item: string) => item)
ForEach(this.arrayJ, (item: string) => {
ListItem() {
Text(item)
.width('80%')
.height('5%')
.fontSize(30)
.textAlign(TextAlign.Center)
}
}, (item: string) => item)
}
.width('50%')
.height('100%')
Column() {
Column() {
AlphabetIndexer({ arrayValue: this.value, selected: 0 })
.autoCollapse(this.isNeedAutoCollapse) // 开启或关闭自适应折叠模式
.height(this.indexerHeight) // 索引条高度
.enableHapticFeedback(false) // 关闭触控反馈
.selectedColor(0xFFFFFF) // 选中项文本颜色
.popupColor(0xFFFAF0) // 提示弹窗一级索引文本颜色
.selectedBackgroundColor(0xCCCCCC) // 选中项背景颜色
.popupBackground(0xD2B48C) // 提示弹窗背景颜色
.usingPopup(true) // 索引项被选中时显示提示弹窗
.selectedFont({ size: 16, weight: FontWeight.Bolder }) // 选中项文本样式
.popupFont({ size: 30, weight: FontWeight.Bolder }) // 提示弹窗内容的文本样式
.itemSize(28) // 每一项的尺寸大小
.alignStyle(IndexerAlign.Right) // 提示弹窗在索引条左侧弹出
.popupTitleBackground("#D2B48C") // 设置提示弹窗一级索引项背景颜色
.popupSelectedColor(0x00FF00) // 提示弹窗二级索引未选中项文本颜色
.popupUnselectedColor(0x0000FF) // 提示弹窗二级索引选中项文本颜色
.popupItemFont({ size: 30, style: FontStyle.Normal }) // 提示弹窗二级索引项文本样式
.popupItemBackgroundColor(0xCCCCCC) // 提示弹窗二级索引项背景颜色
.onSelect((index: number) => {
console.info(this.value[index] + ' Selected!');
})
.onRequestPopupData((index: number) => {
// 当选中A时,提示弹窗里面的二级索引文本列表显示A对应的列表arrayA,选中B、C、L时也同样
// 选中其余索引项时,提示弹窗二级索引文本列表为空,提示弹窗会只显示一级索引项
if (this.value[index] == 'A') {
return this.arrayA;
} else if (this.value[index] == 'B') {
return this.arrayB;
} else if (this.value[index] == 'C') {
return this.arrayC;
} else if (this.value[index] == 'J') {
return this.arrayJ;
} else {
return [];
}
})
.onPopupSelect((index: number) => {
console.info('onPopupSelected:' + index);
})
}
.height('80%')
.justifyContent(FlexAlign.Center)
Column() {
Button('切换成折叠模式')
.margin('5vp')
.onClick(() => {
this.isNeedAutoCollapse = true;
})
Button('切换索引条高度到30%')
.margin('5vp')
.onClick(() => {
this.indexerHeight = '30%';
})
Button('切换索引条高度到70%')
.margin('5vp')
.onClick(() => {
this.indexerHeight = '70%';
})
}
.height('20%')
}
.width('50%')
.justifyContent(FlexAlign.Center)
}
.width('100%')
.height(720)
}
}
}
箭头的效果楼主可以封装一下 限制高度和显式就好,这个效果的视线就是用这个组件做的,也可以自己高度封装一个,
鸿蒙Next中侧边索引条可通过以下方式实现:
- 使用ListContainer组件作为主容器
- 添加IndexBar组件实现索引功能
- 通过IndexBarController控制索引交互
- 在ListContainer的onIndexUpdate回调中处理索引变化
关键代码要点:
- IndexBar需要设置indexes属性(字母数组)
- 实现OnIndexSelectedListener接口处理选中事件
- 使用scrollToIndex方法滚动到对应位置
样式可通过修改IndexBar的以下属性调整:
- indexItemSize:索引项大小
- selectedColor:选中颜色
- normalColor:正常颜色
在HarmonyOS Next中实现这种带向下箭头的侧边索引条,可以通过自定义AlphabetIndexer
组件实现。以下是关键实现思路:
- 继承
AlphabetIndexer
并重写onDraw
方法,在绘制字母列表时添加向下箭头图标 - 使用
Canvas
绘制箭头图标,通常放在字母列表的底部 - 通过
measureText
计算字母占用空间,确保有足够空间显示箭头 - 处理触摸事件时,对箭头区域做特殊处理
核心代码示例:
class CustomIndexer extends AlphabetIndexer {
private arrowHeight = 20 // 箭头高度
onDraw(canvas: Canvas) {
super.onDraw(canvas)
// 在底部绘制箭头
const arrowY = this.height - this.arrowHeight
canvas.drawArrow(/* 箭头绘制参数 */)
}
onTouchEvent(event: TouchEvent): boolean {
const y = event.getY()
// 检查是否点击了箭头区域
if (y > this.height - this.arrowHeight) {
this.handleArrowClick()
return true
}
return super.onTouchEvent(event)
}
}
这种实现方式既保留了原生索引功能,又增加了滚动到底部的快捷操作。