harmony 鸿蒙列表的多级联动

  • 2025-06-16
  • 浏览 (3)

列表的多级联动

场景介绍

多级联动是指根据一个列表(一级列表)的选择结果,来更新另一个列表(二级列表)的选择项,再来更新第三个列表(三级列表)的选择,以此类推。这种联动可以根据用户的实际需求,快速定位到想要的选项,提高交互体验。例如,省市县三级地区的选择、工作部门的选择,本文即为大家介绍如何开发列表的多级联动。

效果呈现

本例效果图如下:

运行环境

本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发: - IDE: DevEco Studio 4.0 Release - SDK: Ohos_sdk_public 4.0.10.13 (API Version 10 Release)

实现思路

本例关键功能点及其实现思路如下: - 文本选择弹窗:通过CompanyDialogController实现。

  • 点击公司列表弹出对应旗下子公司的列表,点击子公司列表弹出对应的旗下部门的网格:通过ForEach的嵌套使用进行循环渲染公司列表、子公司列表、部门。

开发步骤

根据实现思路,具体开发步骤如下: 1. 构建列表数据。

```ts
// LinkageData.ets
export interface Link{
  name:string
  Subsidiary:a[]
}
export interface a{
  name:string,
department:Array<string>
}
export const LinkageData:Link[]=[
  {
    name:"A公司",
    Subsidiary:[
      {
        name:"a子公司",
        department:[
          "技术部",
          "工程部",
          "维护部",
          "运营部",
          "售后部"
        ]
      },
      {
        name:"b子公司",
        department:[
          "行政部",
          "管理部",
          "服务部",
          "秘书部"
        ]
      },
      {
        name:"c子公司",
        department:[
          "行动部",
          "情报部",
          "信息部"
        ]
      }
    ]
  },
...
]
```
  1. 打开自定义弹窗。通过CustomDialogController以实现自定义弹窗的打开。

    // Index.ets
    ...
    CompanyDialogController:CustomDialogController = new CustomDialogController({
      builder:CompanyPicker({
        postA:$postA,
        company:$companyButtonTitle,
        companyStringArray:this.CompanyArray
      }),
      autoCancel:true,
      alignment:DialogAlignment.Bottom,
      customStyle:true
    })
    
    
    build() {
      Column(){
        Text(this.companyButtonTitle)
          .height(50)
          .fontSize(30)
          .borderRadius(10)
          .backgroundColor(0xFFFFFF)
          .onClick(()=>{
            this.CompanyDialogController.open();
          })
      }.width('100%').height('100%')
      .backgroundColor(Color.White)
      .padding({top:5})
    }
    ...         
    
  2. 具体部门的选择。通过ForEach的嵌套使用循环渲染公司列表、子公司列表、部门。通过点击事件将具体部门展示到弹窗上方,点击确定后,界面显示具体部门。

    //  Index.ets
    ...
    List({space:15, initialIndex:0,scroller:this.scroller}){
      ForEach(LinkageData,(Item:Link)=>{
        ListItem() {
          Column() {
            Text(`${Item.name === '' ? Item : Item.name}`)
              .height(40)
              .fontSize(30)
              .fontColor('#000000')
              .width('100%')
              .margin({ top: 10 })
              .onClick(() => {
                if (this.isCompany === Item.name) {
                  this.isCompany = ''
                } else {
                  this.isCompany = Item.name
                }
              })
            if (this.isCompany === Item.name) {
              List({ space: 10 }) {
                ForEach(Item.Subsidiary, (ItemA: a) => {
                  ListItem() {
                    Column() {
                      Text(`${Item.name === undefined ? ItemA : ItemA.name}`)
                        .width('100%')
                        .height(20)
                        .fontSize(18)
                        .margin({ top: 4 })
                        .onClick(() => {
                          if (this.isSubsidiaryAA === ItemA.name) {
                            this.isSubsidiaryAA = ''
                          } else {
                            this.isSubsidiaryAA = ItemA.name
                          }
                        })
                        if (this.isSubsidiaryAA === ItemA.name) {
                          Grid() {
                            ForEach(ItemA.department, (departmentName: string) => {
                              GridItem() {
                                Text(`${departmentName}`)
                                  .margin({ top: 10, bottom: 10 })
                                  .fontSize(14)
                                  .maxLines(5)
                                  .fontColor(Color.Black)
                                  .borderRadius(5)
                                  .padding(5)
                                  .backgroundColor('#00FFFF')
                                  .onClick(() => {
                                    this.tempDepartment = `${Item.name}${ItemA.name}${departmentName}`
                                  })
                              }
                            })
                          }.width('100%')
                          .height(100)
                          .columnsTemplate('1fr 1fr')
                        }
                    }
                  }
                })
              }
            }
          }
        }
      })
    }
    ...
    
  3. 自定义弹窗的关闭。

    // Index.ets
    ...
    Row(){
      Text(this.tempDepartment)
        .fontSize(14)
        .fontColor(Color.White)
        .layoutWeight(1)
        .height(40)
      Button("确定",{type:ButtonType.Normal,stateEffect:true})
        .fontSize(14)
        .fontColor(Color.White)
        .layoutWeight(1)
        .height(40)
        .onClick(()=>{
          this.company = this.tempDepartment
          if (this.controller !== undefined){
            this.controller.close()
          }
        })
    }
    ...
    

    完整代码

    在LinkageData.ets根据效果开发者自行进行编辑,在Index.ets在开发步骤中基本展示全部代码。

    参考

    自定义弹窗

循环渲染

你可能感兴趣的鸿蒙文章

harmony 鸿蒙导航栏的使用编辑

harmony 鸿蒙Tab组件如何实现增删Tab标签

harmony 鸿蒙如何自定义鼠标悬停/点击组件的背景色

harmony 鸿蒙案例介绍

harmony 鸿蒙搜索框与文字轮播的巧用

harmony 鸿蒙使用Badge组件完成聊天未读消息数量显示功能

harmony 鸿蒙如何开发自适应布局

harmony 鸿蒙应用质量提升案例-应用Crash闪退问题案例分析

harmony 鸿蒙应用质量提升案例-稳定性测试常见JS_ERROR问题分析与定位

harmony 鸿蒙如何通过显示动画实现书籍翻页动效

0  赞