HarmonyOS 鸿蒙Next中提供一个Search组件全场景实战介绍?

HarmonyOS 鸿蒙Next中提供一个Search组件全场景实战介绍? 搜索框是我们开发中高频使用的组件,能否提供一个Search组件全场景实战介绍?

包含样式自定义、多场景交互、功能扩展等功能需求

4 回复

我们在鸿蒙应用开发中,搜索框是高频核心组件,无论是内容检索、信息查询还是功能入口,都离不开灵活易用的 Search 组件。这里我提供多个使用实例,满足整合样式自定义、多场景交互、功能扩展等需求

一、使用场景

基础样式定制:自定义搜索图标、清除按钮、占位文本样式;

输入控制:限制输入类型(数字 / 邮箱 / 手机号)、最大长度、输入过滤;

交互增强:自定义键盘、回车类型切换、文本选择与编辑回调;

高级扩展:文本描边、中西文自动间距、字体自适应缩放。

二、关键代码实现

  1. 基础样式定制

图标自定义:通过searchIcon和cancelButton属性配置搜索图标、清除按钮的路径、颜色和尺寸,支持系统图标($r(“sys.media.*”))或自定义图片;

文本样式:placeholderFont和textFont分别控制占位文本和输入文本的字号、粗细,fontColor设置输入文本颜色;

外观优化:圆角边框(borderRadius)+ 浅色背景,符合现代 UI 设计风格,光标样式通过caretStyle自定义颜色和宽度。

     Text("基础样式:自定义图标+占位文本")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        value: this.inputValue,
        placeholder: "请输入搜索内容(支持中英文)",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5) // 圆角优化
        .padding({ left: 15 })
        // 自定义搜索图标(API 10+)
        .searchIcon({
          src: $r("sys.media.ohos_ic_public_search_filled"),
          color: "#3498DB",
          size: "20vp"
        })
        // 自定义清除按钮(API 10+)
        .cancelButton({
          style: CancelButtonStyle.INPUT,
          icon: {
            src: $r("sys.media.ohos_ic_public_cancel_filled"),
            color: "#999999",
            size: "18vp"
          }
        })
        // 占位文本样式
        .placeholderColor("#999999")
        .placeholderFont({ size: 15, weight: FontWeight.Normal })
        // 输入文本样式
        .textFont({ size: 16, weight: FontWeight.Medium })
        .fontColor("#333333")
        // 光标样式(API 10+)
        .caretStyle({ width: 2, color: "#3498DB" })
        // 输入变化回调
        .onChange((value: string) => {
          this.inputValue = value;
        })
        // 搜索提交回调
        .onSubmit((value: string) => {
          this.submitResult = `搜索结果:${value}`;
        })
        .margin({ bottom: 25 });
  1. 输入控制与校验

输入类型限制:type属性支持SearchType.NUMBER(纯数字)、SearchType.EMAIL(邮箱)、SearchType.PHONE_NUMBER(手机号)等,自动适配对应输入法;

长度与过滤:maxLength限制最大输入字符数,inputFilter通过正则表达式过滤非法输入(如示例中仅允许数字和小数点);

输入回调:onChange实时监听输入变化,onSubmit在点击搜索按钮或输入法回车时触发。

  // 2. 输入控制版Search(数字+小数点输入)
      Text("输入控制:仅允许数字+小数点")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        placeholder: "请输入数字(如金额、年龄)",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5)
        .padding({ left: 15 })
        // 输入类型限制为带小数点的数字(API 12+)
        .type(SearchType.NUMBER_DECIMAL)
        // 最大输入长度限制(API 11+)
        .maxLength(10)
        // 输入过滤:仅允许数字和小数点(API 12+)
        .inputFilter("[0-9.]+", (filtered: string) => {
          this.filteredText = `被过滤的内容:${filtered}`;
        })
        .margin({ bottom: 25 });
  1. 交互增强功能

自定义键盘:通过customKeyboard绑定@Builder构建的自定义键盘(如示例中的数字键盘),适合密码、验证码等场景;

回车类型切换:enterKeyType支持Search/Go/Send/Done等类型,适配不同业务场景(如搜索、提交、下一步);

编辑态控制:通过SearchController的stopEditing方法关闭键盘,caretPosition设置光标位置。

 // 3. 自定义键盘版Search
      Text("交互增强:自定义数字键盘")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        placeholder: "点击唤起自定义数字键盘",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5)
        .padding({ left: 15 })
        // 绑定自定义键盘(API 10+)
        .customKeyboard(this.CustomNumberKeyboard())
        .margin({ bottom: 25 });
  1. 高级扩展能力

文本描边(API 20+):通过strokeWidth和strokeColor设置文本描边宽度和颜色,实现空心字效果;

中西文自动间距(API 20+):enableAutoSpacing(true)自动优化中文与英文、数字之间的间距,提升阅读体验;

字体缩放限制(API 18+):minFontScale和maxFontScale控制文本最大 / 最小缩放比例,适配系统字体大小调整;

自定义编辑菜单(API 12+):通过editMenuOptions扩展文本选择菜单(如添加 “翻译”“分享” 按钮)。

 // 4. 回车类型切换演示
      Button(`切换回车类型(当前:${this.enterKeyTypes[this.currentEnterKeyIndex].toString()}`)
        .width("90%")
        .height(40)
        .backgroundColor("#3498DB")
        .fontColor("#FFFFFF")
        .borderRadius(20)
        .onClick(() => {
          this.currentEnterKeyIndex = (this.currentEnterKeyIndex + 1) % this.enterKeyTypes.length;
        })
        .margin({ bottom: 15 });

      // 状态提示区
      Text(this.submitResult)
        .fontSize(15)
        .margin({ bottom: 10 });
      Text(this.filteredText)
        .fontSize(14)
        .fontColor("#FF4444")
        .margin({ bottom: 20 });

      // 高级功能说明
      Text("高级功能支持:")
        .fontSize(14)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 5 });
      Text("• 文本描边(API 20+)• 中西文自动间距(API 20+)")
        .fontSize(13)
        .fontColor("#666666");
      Text("• 字体缩放限制(API 18+)• 自定义编辑菜单(API 12+)")
        .fontSize(13)
        .fontColor("#666666");
    }
    .width("100%")
    .height("100%")
    .backgroundColor("#F5F5F5");

三、完整代码

@Entry
@Component
struct SearchComprehensiveDemo {
  // 响应式状态:输入值、提交结果、过滤提示
  @State inputValue: string = "";
  @State submitResult: string = "未提交搜索";
  @State filteredText: string = "";
  // 控制器:用于光标操作、文本选择、关闭编辑态
  private searchController: SearchController = new SearchController();
  // 回车类型列表(用于切换演示)
  private enterKeyTypes: EnterKeyType[] = [
    EnterKeyType.Search, EnterKeyType.Go, EnterKeyType.Send, EnterKeyType.Done
  ];
  @State currentEnterKeyIndex: number = 0;

  // 自定义键盘构建器(API 10+支持)
  [@Builder](/user/Builder) CustomNumberKeyboard() {
    Column() {
      // 关闭键盘按钮
      Button("关闭键盘")
        .width("100%")
        .height(40)
        .backgroundColor("#FF4444")
        .fontColor("#FFFFFF")
        .onClick(() => {
          this.searchController.stopEditing(); // 退出编辑态,关闭键盘
        });
      // 数字键盘网格
      Grid() {
        ForEach(["1", "2", "3", "4", "5", "6", "7", "8", "9", "删除", "0"], (item: string) => {
          GridItem() {
            Button(item)
              .width("100%")
              .height(60)
              .onClick(() => {
                if (item === "删除") {
                  this.inputValue = this.inputValue.slice(0, -1);
                } else {
                  this.inputValue += item;
                }
              });
          }
        });
      }
      .columnsGap(5)
      .rowsGap(5)
      .maxCount(3) // 3列布局
      .padding(10)
      .backgroundColor("#F5F5F5");
    }
  }

  build() {
    Column() {
      // 功能标题
      Text("Search组件全功能演示")
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .margin({ top: 30, bottom: 20 });

      // 1. 基础样式定制版Search
      Text("基础样式:自定义图标+占位文本")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        value: this.inputValue,
        placeholder: "请输入搜索内容(支持中英文)",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5) // 圆角优化
        .padding({ left: 15 })
        // 自定义搜索图标(API 10+)
        .searchIcon({
          src: $r("sys.media.ohos_ic_public_search_filled"),
          color: "#3498DB",
          size: "20vp"
        })
        // 自定义清除按钮(API 10+)
        .cancelButton({
          style: CancelButtonStyle.INPUT,
          icon: {
            src: $r("sys.media.ohos_ic_public_cancel_filled"),
            color: "#999999",
            size: "18vp"
          }
        })
        // 占位文本样式
        .placeholderColor("#999999")
        .placeholderFont({ size: 15, weight: FontWeight.Normal })
        // 输入文本样式
        .textFont({ size: 16, weight: FontWeight.Medium })
        .fontColor("#333333")
        // 光标样式(API 10+)
        .caretStyle({ width: 2, color: "#3498DB" })
        // 输入变化回调
        .onChange((value: string) => {
          this.inputValue = value;
        })
        // 搜索提交回调
        .onSubmit((value: string) => {
          this.submitResult = `搜索结果:${value}`;
        })
        .margin({ bottom: 25 });

      // 2. 输入控制版Search(数字+小数点输入)
      Text("输入控制:仅允许数字+小数点")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        placeholder: "请输入数字(如金额、年龄)",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5)
        .padding({ left: 15 })
        // 输入类型限制为带小数点的数字(API 12+)
        .type(SearchType.NUMBER_DECIMAL)
        // 最大输入长度限制(API 11+)
        .maxLength(10)
        // 输入过滤:仅允许数字和小数点(API 12+)
        .inputFilter("[0-9.]+", (filtered: string) => {
          this.filteredText = `被过滤的内容:${filtered}`;
        })
        .margin({ bottom: 25 });

      // 3. 自定义键盘版Search
      Text("交互增强:自定义数字键盘")
        .fontSize(14)
        .margin({ left: 15, bottom: 5 })
        .textAlign(TextAlign.Start)
        .width("100%");
      Search({
        placeholder: "点击唤起自定义数字键盘",
        controller: this.searchController
      })
        .width("90%")
        .height(45)
        .backgroundColor("#F8F9FA")
        .borderRadius(22.5)
        .padding({ left: 15 })
        // 绑定自定义键盘(API 10+)
        .customKeyboard(this.CustomNumberKeyboard())
        .margin({ bottom: 25 });

      // 4. 回车类型切换演示
      Button(`切换回车类型(当前:${this.enterKeyTypes[this.currentEnterKeyIndex].toString()}`)
        .width("90%")
        .height(40)
        .backgroundColor("#3498DB")
        .fontColor("#FFFFFF")
        .borderRadius(20)
        .onClick(() => {
          this.currentEnterKeyIndex = (this.currentEnterKeyIndex + 1) % this.enterKeyTypes.length;
        })
        .margin({ bottom: 15 });

      // 状态提示区
      Text(this.submitResult)
        .fontSize(15)
        .margin({ bottom: 10 });
      Text(this.filteredText)
        .fontSize(14)
        .fontColor("#FF4444")
        .margin({ bottom: 20 });

      // 高级功能说明
      Text("高级功能支持:")
        .fontSize(14)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 5 });
      Text("• 文本描边(API 20+)• 中西文自动间距(API 20+)")
        .fontSize(13)
        .fontColor("#666666");
      Text("• 字体缩放限制(API 18+)• 自定义编辑菜单(API 12+)")
        .fontSize(13)
        .fontColor("#666666");
    }
    .width("100%")
    .height("100%")
    .backgroundColor("#F5F5F5");
  }
}

四、效果展示

cke_23897.png

更多关于HarmonyOS 鸿蒙Next中提供一个Search组件全场景实战介绍?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


小伙伴你好,可以参考文档

文本输入 (TextInput/TextArea/Search)

Search组件

鸿蒙Next的Search组件支持全场景统一搜索体验,可在手机、平板、智慧屏等多设备上使用。它提供实时搜索建议、历史记录展示及结果高亮功能。开发者可通过ArkTS声明式UI快速集成,自定义搜索框样式与交互逻辑。该组件适配不同设备形态,并支持跨端协同搜索能力。

在HarmonyOS Next中,Search组件(Search)是构建高效搜索功能的核心。以下是一个全场景实战介绍,涵盖样式自定义、多场景交互与功能扩展:

1. 基础使用与样式自定义

  • 基础集成:通过Search组件快速创建搜索框,支持占位符、图标和输入回调。
    Search({ placeholder: '请输入关键词' })
      .onChange((value: string) => {
        console.info(`搜索内容: ${value}`);
      })
    
  • 样式自定义
    • 外观:通过backgroundColorborderRadius等属性调整背景、圆角。
    • 图标:自定义搜索图标(searchIcon)和清除按钮图标(closeIcon)。
    • 文本样式:使用placeholderFonttextFont设置字体大小、颜色。
    Search({ placeholder: '搜索' })
      .searchIcon($r('app.media.custom_icon'))
      .backgroundColor(Color.White)
      .borderRadius(20)
    

2. 多场景交互实现

  • 实时搜索:结合onChange事件监听输入内容,动态过滤本地数据或触发网络请求。
  • 搜索历史:通过本地存储(Preferences)记录历史关键词,以下拉列表形式展示。
  • 联想建议:输入时调用接口获取联想词,使用List组件展示并支持点击填充。
  • 多端适配:通过响应式布局(如栅格系统、媒体查询)适配手机、平板等不同设备。

3. 功能扩展与高级特性

  • 语音搜索:集成AudioSpeechToText能力,通过麦克风图标触发语音输入。
  • 扫码搜索:结合CameraScan组件,调用摄像头扫描条形码/二维码作为输入。
  • 高级筛选:在搜索框旁添加筛选按钮,结合Panel或弹窗展开多条件过滤选项。
  • 动画效果:使用animateTo实现搜索框展开/收起、结果列表淡入淡出等交互动画。

4. 性能与体验优化

  • 防抖处理:通过debounce减少onChange事件的频繁触发,优化网络请求频率。
  • 异步加载:搜索结果显示大量数据时,使用LazyForEach实现列表懒加载。
  • 空状态提示:无结果时展示友好提示(如“未找到相关内容”)。

5. 实战示例:综合搜索页面

// 结合历史记录、联想建议和实时筛选的完整示例
[@State](/user/State) query: string = '';
[@State](/user/State) historyList: string[] = [];
[@State](/user/State) suggestionList: string[] = [];

build() {
  Column() {
    Search({ placeholder: '搜索商品' })
      .onChange((value: string) => {
        this.query = value;
        this.getSuggestions(value); // 获取联想词
      })
      .onSubmit(() => {
        this.saveHistory(this.query); // 保存历史
        this.searchData(this.query); // 执行搜索
      })

    // 搜索历史
    if (this.historyList.length > 0 && !this.query) {
      List({ space: 10 }) {
        ForEach(this.historyList, (item: string) => {
          ListItem() {
            Text(item).onClick(() => this.query = item)
          }
        })
      }
    }

    // 联想建议
    if (this.suggestionList.length > 0) {
      List() {
        ForEach(this.suggestionList, (item: string) => {
          ListItem() {
            Text(item).onClick(() => {
              this.query = item;
              this.searchData(item);
            })
          }
        })
      }
    }
  }
}

总结

HarmonyOS Next的Search组件通过灵活的API和扩展能力,可覆盖从基础搜索到语音、扫码等复杂场景。开发者可通过样式定制、交互事件与原生能力集成,构建体验一致的跨设备搜索功能。

回到顶部