ArkUI自定义一个简单的带搜索功能的列表

276 阅读3分钟

又到了午休吃饭的时候啦,趁着大家睡觉的时间赶紧努力写个博客吧!今天和大家分享一个比较简单的自定义列表界面。由于每天学习的时间是有限的,所以封装的组件名称是自己瞎写的,里边字段名称也没好好起一下,不过重在研究。后续会持续分享鸿蒙学习,感兴趣的可以一起交流,加个关注。demo下载链接

Screenshot_2024-11-18T133453.png

Screenshot_2024-11-18T133420.png

1. 实现的代码

@ComponentV2
export  default   struct CustomNavgation {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  private imgArr: string[] = ["a","b","c","d","e","f","touxiang","ic_start_icon","icon","banner_pic0"];
  private positiveMessages: string[] = [
    "每一天都是新的起点。",
    "快乐是选择,不是条件。",
    "你的努力会带来改变。",
    "相信自己,你比想象中强大。",
    "小进步,大成就。",
    "积极的态度决定一切。",
    "追梦路上,每一步都算数。",
    "不怕路长,只怕志短。",
    "每个早晨,都是对生活的重新开始。",
    "今天会更好,因为有你在。"
  ];
  @Local searchKeyword: string = '';///存储关键字

  @Builder NavigationTitle() {
    Column() {
      Text('发现')
        .fontColor('#182431')
        .fontSize(30)
        .lineHeight(41)
        .fontWeight(700)
        .margin({left: 10})

      Text('永远要用心去发现世界的美!')
        .fontColor('#182431')
        .fontSize(14)
        .lineHeight(19)
        .opacity(0.4)
        .margin({left: 10, top: 2, bottom: 20 })

    }.alignItems(HorizontalAlign.Start)
  }

  @Builder NavigationMenus() {
    Row() {
      Image($r("app.media.touxiang"))
        .width(24)
        .height(24)
      Image($r("app.media.startIcon"))
        .width(24)
        .height(24)
        .margin({ left: 24 })
      Image($r("app.media.ic_start_icon"))
        .width(24)
        .height(24)
        .margin({ left: 24 })
    }

  }

  @Computed  get filteredItems() {
    console.log('filteredItems called with searchIndex:', this.searchKeyword); // 调试输出
    if (!this.searchKeyword) {
      return this.arr; // 如果没有输入索引值,显示全部12条数据
    }
    const index = parseInt(this.searchKeyword, 10);
    if (isNaN(index) || index < 0 || index >= this.arr.length) {
      return []; // 输入无效索引值时,不显示任何数据
    }
    return [this.arr[index]]; // 根据输入的索引值筛选数据
  }


  getRandomMessage() {
    const randomIndex = Math.floor(Math.random() * this.positiveMessages.length);
    return this.positiveMessages[randomIndex];
  }
  build() {
    Column() {
      Navigation() {
        TextInput({ placeholder: 'search...' })
          .width('90%')
          .height(40)
          .backgroundColor('#FFFFFF')
          .margin({ top: 8 })
          .onChange((value: string) => {
            this.searchKeyword = value
          })

        List({ space: 12, initialIndex: 0 }) {
          ForEach(this.filteredItems, (item: number) => {
            ListItem() {
            Row(){
              Text((item + 1).toString())
                .margin({left : 15 })
                .width('%40')
                .height(72)
                .fontSize(20)
                .fontColor('black')
                .fontWeight(500)
                .textAlign(TextAlign.Start)

              Image($r(`app.media.${this.imgArr[item]}`))
                .width(56)
                .height(56)
                .margin({ left: 20 })
                .borderRadius(5)

              // 添加正面消息
              Text(this.getRandomMessage())
                .fontSize(14)
                .fontColor('blue')
                .margin({ left: 20 })

               }
               .width('90%')
               .height(86)
               .backgroundColor('#FFFFFF')
               .borderRadius(24)
            }
          }, (item: number) => item.toString())
        }
        .height('90%')
        .width('100%')
        .margin({ top: 12, left: '10%' })
      }
      .title(this.NavigationTitle)
      .menus(this.NavigationMenus)
      .titleMode(NavigationTitleMode.Full)
      .hideTitleBar(false)
      .hideToolBar(false)
      .onTitleModeChange((titleModel: NavigationTitleMode) => {
        console.info('titleMode' + titleModel)
      })
    }.width('100%').height('100%').backgroundColor('#F1F3F5')
  }

}

2. 代码解释说明

  • @ComponentV2:这是一个装饰器,用于声明CustomNavigation()是一个组件。
  • export default struct CustomNavigation:这行代码定义了一个名为CustomNavigation的默认导出组件。
  • 这里的struct指在该框架中用于定义组件的一种方式。
  • build() 方法:这是组件的主要构建方法,在这里定义了组件的UI布局。

(1)、参数说明

  • arr: 一个数字数组,包含0到9共10个元素。

  • imgArr: 一个字符串数组,包含了一些图片资源的名字。

  • positiveMessages: 一个字符串数组,包含了一些正面鼓励的消息,用于在列表项中随机显示。

  • @Local searchKeyword: 一个本地变量,用于存储用户在搜索框中输入的关键字。

  • @Computed get filteredItems(): 这是一个计算属性,根据searchKeyword的值来过滤arr数组中的项目。如果没有输入关键字,则显示所有项目;如果输入了有效的数字索引,则只显示对应的项目;如果是无效的索引值,则不显示任何项目。

(2)、 构建方法

  • NavigationTitle()NavigationMenus():这两个方法分别用于构建导航栏的标题和菜单部分。它们使用了ColumnRow布局来组织文本和图片元素。
  • getRandomMessage():这个方法从positiveMessages数组中随机选取一条消息返回,用于在列表项中显示。

(3)、主体布局

  • TextInput:定义了一个搜索输入框,当用户输入时,会触发onChange事件更新searchKeyword的值,从而影响filteredItems的计算结果。
  • List:定义了一个列表,使用ForEach循环遍历filteredItems,为每个项目创建一个ListItem
  • ListItem:每个列表项都包含了编号、图片和一条随机的正面消息。
  • Navigation:定义了整个页面的导航部分,包括标题、菜单、标题模式等。

(4)、样式与布局

  • 使用了多种样式属性如fontColorfontSizemargin等来定制组件的外观。
  • 布局方面,通过ColumnRow来组织子元素,确保了良好的视觉效果。