OpenHarmony开发者论坛
标题:
如何实现列表的二级联动
[打印本页]
作者:
一只杨
时间:
2023-8-25 10:04
标题:
如何实现列表的二级联动
[md]【问题描述】
我想实现两个列表,当选中第一个列表的值,第二个列表也会发生联动,如何实现列表的二级联动?
比如下面的界面在选择照片滤镜时,当选择滤镜分类列表,下面的效果展示列表会的快速定位到想要的选项。
![qwe.png](data/attachment/forum/202308/25/100415ittr90mrkkqtk5a9.png "qwe.png")
【运行环境】
硬件:rk3568; ROM: 3.2 Release; API 9
[/md]
作者:
18219201129
时间:
2023-8-25 16:20
[md]你好,我们来实现一个数字标题和数字列表(contents)分组的二级联动。
实现思路
●数字标题(titles)以及下方的数字列表(contents)分组展示:通过两个List组件分别承载数字标题和数字项。
●滚动数字列表,上方数字标题也随之变动:通过List组件的onScrollIndex事件获取到当前滚动数字的索引,根据该索引计算出对应标题数字的索引,然后通过Scroller的scrollToIndex方法跳转到对应的数字标题,且通过Line组件为选中的标题添加下划线。
●点击数字标题,下方的数字列表也随之变化:首先获取到点击数字标题的索引,通过该索引计算出下方对应数字的起始项索引,然后通过scroller的scrollToIndex方法跳转到对应索引的数字项。
开发步骤
根据实现思路,具体实现步骤如下:
1.首先构建列表数据,在records中记录数字列表中各个数字的首项索引值,具体代码块如下:
```
...
@State typeIndex: number = 0
private tmp: number = 0
private titles: Array<string> = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
private contents: Array<string> = ["1", "1", "1", "1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "3"
, "3", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "5", "6", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7",
"8", "8", "8", "8", "8", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9"]
private records: Array<number> = [0, 9, 21, 26, 29, 34, 35, 47, 52, 63]
private classifyScroller: Scroller = new Scroller();
private scroller: Scroller = new Scroller();
...
```
数字标题列表:具体代码块如下:
```
...
build() {
Column({ space: 0 }) {
List ({ space: 50, scroller: this.classifyScroller, initialIndex: 0 }) {
ForEach(this.titles, (item, index) => {
ListItem() {
Column() {
Text(item)
.fontSize(14)
...
}
}
}
...
}
.listDirection(Axis.Horizontal)
.height(50)
}
}
```
数字列表,具体代码块如下:
```
List({ space: 20, scroller: this.scroller }) {
ForEach(this.contents, (item, index) => {
ListItem() {
Column({ space: 5 }) {
Image($r("app.media.app_icon"))
.width(40)
.height(40)
Text(item)
.fontSize(12)
}
...
}
}
}
.listDirection(Axis.Horizontal) //列表排列方向水平
.edgeEffect(EdgeEffect.None) //不支持滑动效果
```
2.数字标题的索引值判断,根据当前滚动数字的首项索引值计算出数字标题的索引,具体代码块如下:
```
...
findClassIndex(ind: number) { // 当前界面最左边图的索引值ind
let ans = 0
// 定义一个i 并进行遍历 this.records.length = 10
for (let i = 0; i < this.records.length; i++) {
// 判断ind在this.records中那两个临近索引值之间
if (ind >= this.records
&& ind < this.records[i + 1]) {
ans = i
break
}
}
return ans
}
findItemIndex(ind: number) {
// 将ind重新赋值给类型标题列表的索引值
return this.records[ind]
}
...
```
通过Line组件构成标题下滑线,具体代码块如下:
```
...
if (this.typeIndex == index) {
Line()
//根据长短判断下划线
.width(item.length === 2 ? 25 : item.length === 3 ? 35 : 50)
.height(3)
.strokeWidth(20)
.strokeLineCap(LineCapStyle.Round)
.backgroundColor('#ffcf9861')
}
...
```
3.点击数字标题,数字列表随之滑动:首先获取到点击数字标题的索引,通过该索引计算出下方对应数字的起始项索引,然后通过scroller的scrollToIndex方法跳转到对应索引的数字项,具体代码块如下:
```
...
.onClick(() => {
this.typeIndex = index
this.classifyScroller.scrollToIndex(index)
let itemIndex = this.findItemIndex(index)
console.log("移动元素:" + itemIndex)
this.scroller.scrollToIndex(itemIndex)
})
...
```
4.数字列表的滑动或点击导致数字标题的变动:通过List组件中onScrollIndex事件获取的到屏幕中最左边数字的索引值start,然后通过该索引值计算出对应的数字标题的索引currentClassIndex,然后通过scrollToIndex控制数字标题跳转到对应索引处,具体代码块如下:
```
...
.onScrollIndex((start) => {
let currentClassIndex = this.findClassIndex(start)
console.log("找到的类索引为: " + currentClassIndex)
if (currentClassIndex != this.tmp) {
this.tmp = currentClassIndex
console.log("类别移动到索引: " + currentClassIndex)
this.typeIndex = currentClassIndex
this.classifyScroller.scrollToIndex(currentClassIndex)
}
})
...
```
完整代码
```
@Entry
@Component
struct TwoLevelLink {
@State typeIndex: number = 0
private tmp: number = 0
private titles: Array<string> = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]
private contents: Array<string> = ["1", "1", "1", "1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "3"
, "3", "3", "3", "3", "4", "4", "4", "5", "5", "5", "5", "5", "6", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7", "7",
"8", "8", "8", "8", "8", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9", "9"]
private colors: Array<string> = ["#18183C", "#E8A027", "#D4C3B3", "#A4AE77", "#A55D51", "#1F3B54", "#002EA6", "#FFE78F", "#FF770F"]
private records: Array<number> = [0, 9, 21, 26, 29, 34, 35, 47, 52, 63]
private classifyScroller: Scroller = new Scroller();
private scroller: Scroller = new Scroller();
// 根据数字列表索引计算对应数字标题的索引
findClassIndex(ind: number) {
let ans = 0
for (let i = 0; i < this.records.length; i++) {
if (ind >= this.records
&& ind < this.records[i + 1]) {
ans = i
break
}
}
return ans
}
// 根据数字标题索引计算对应数字列表的索引
findItemIndex(ind: number) {
return this.records[ind]
}
build() {
Column({ space: 0 }) {
List ({ space: 50, scroller: this.classifyScroller, initialIndex: 0 }) {
ForEach(this.titles, (item, index) => {
ListItem() {
Column() {
Text(item)
.fontSize(24)
if (this.typeIndex == index) {
Line()
.width(item.length === 2 ? 25 : item.length === 3 ? 35 : 50)
.height(3)
.strokeWidth(20)
.strokeLineCap(LineCapStyle.Round)
.backgroundColor('#ffcf9861')
}
}
.onClick(() => {
this.typeIndex = index
this.classifyScroller.scrollToIndex(index)
let itemIndex = this.findItemIndex(index)
console.log("移动元素:" + itemIndex)
this.scroller.scrollToIndex(itemIndex)
})
}
})
}
.listDirection(Axis.Horizontal)
.height(50)
List({ space: 20, scroller: this.scroller }) {
ForEach(this.contents, (item, index) => {
ListItem() {
Column({ space: 5 }) {
Text(item)
.fontSize(30)
.fontColor(Color.White)
}
.width(60)
.height(60)
.backgroundColor(this.colors[item-1])
.justifyContent(FlexAlign.Center)
.onClick(() => {
this.scroller.scrollToIndex(index)
})
}
})
}
.listDirection(Axis.Horizontal) //列表排列方向水平
.edgeEffect(EdgeEffect.None) //不支持滑动效果
.onScrollIndex((start) => {
let currentClassIndex = this.findClassIndex(start)
console.log("找到的类索引为: " + currentClassIndex)
if (currentClassIndex != this.tmp) {
this.tmp = currentClassIndex
console.log("类别移动到索引: " + currentClassIndex)
this.typeIndex = currentClassIndex
this.classifyScroller.scrollToIndex(currentClassIndex)
}
})
}.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
}
}
```
[/md]
欢迎光临 OpenHarmony开发者论坛 (https://forums.openharmony.cn/)
Powered by Discuz! X3.5