深度解析:ArkUI 中的自适应宽度输入框与点击保存功能 原创

在敲键盘的小鱼干很饥饿
发布于 2024-12-25 14:07
浏览
0收藏

引言

在日常的开发中,遇到需要更改用户名的UI设计,然而却遇到一些麻烦,比如用户名过长输入框不够怎么办,怎么去掉光标并保存输入等,在文档中查询还是很慢的,所以就对之前的困难做一个总结,本文将探讨如何使其宽度自适应、如何通过点击屏幕保存用户输入,以及如何去掉光标等技术细节。

输入框的基础设置

在 ArkUI 中,TextInput组件是用于接收用户输入的基本组件。下面我们将详细介绍如何设置这个组件的各种属性,以实现一个功能丰富且美观的输入框。
基本用法

TextInput({
  'placeholder': "请输入标题",
  'text': this.idCityTitleModel.title,
})

placeholder:设置输入框的占位符文本,当用户没有输入内容时,会显示这个文本。
text:设置输入框的初始文本内容,通常是通过状态管理来动态获取。
样式设置

.backgroundColor($r('app.color.background_color_lv3'))
.fontColor($r("app.color.main_font"))
.fontSize(24)
.width("auto")
.height(40)
.borderRadius(5)
.padding({ right: 5 })
  • backgroundColor:设置输入框的背景颜色。
  • fontColor:设置输入框中的字体颜色。
  • fontSize:设置输入框中字体的大小。
  • width:设置输入框的宽度,这里使用"auto"来实现宽度自适应。
  • height:设置输入框的高度。
  • borderRadius:设置输入框的圆角,使外观更加柔和。
  • padding:设置输入框的内边距,以优化文本与边框的距离。

内容类型和输入类型

.type(InputType.USER_NAME)
.contentType(ContentType.USER_NAME)

type:设置输入框的输入类型,这里设置为USER_NAME,表示输入框用于输入用户名或标题。
contentType:设置输入框的内容类型,同样设置为USER_NAME,用于控制输入内容的过滤和验证。
光标样式

.caretStyle({ width: 1.5, color: '#000000' })

caretStyle:设置光标的宽度和颜色,这里将光标的宽度设置为1.5像素,颜色设置为黑色。
焦点状态

.focusable(this.isShowInput)

focusable:设置输入框是否可获得焦点,当this.isShowInput为true时,输入框才能获得焦点显示光标。可以将isShowInput绑定在任意位置即可。
取消按钮

.cancelButton({
  style: CancelButtonStyle.CONSTANT,
  icon: {
    src: $r('app.media.bond_pen_svg'),
    size: 16,
    color: $r('app.color.menu_font_color')
  }
})

cancelButton:设置取消按钮的样式和图标。这里使用了CONSTANT样式,表示取消按钮始终显示,并设置了图标的源、大小和颜色。注意这里的图片用svg,再设置颜色就可以填充,在深色模式也适配。和fillcolor类似

宽度自适应

在 ArkUI 中,我们可以通过将 width 属性设置为 “auto” 来让输入框的宽度根据其内容自动调整

.width("auto")

width(“auto”):该设置使得输入框的宽度根据输入的内容动态调整,而不是固定在一个特定的宽度值。这有助于在内容较短时节省空间,而在内容较长时自动扩展,从而提升用户体验。
说明:
在TextInput组件中,width设置auto表示自适应文本宽度。
在AlphabetIndexer组件中,width设置auto表示自适应宽度最大索引项的宽度。
在Row、Column、RelativeContainer组件中,width、height设置auto表示自适应子组件。
演示:
深度解析:ArkUI 中的自适应宽度输入框与点击保存功能-鸿蒙开发者社区

点击屏幕保存并去掉光标

基本功能介绍

点击屏幕保存功能允许用户在编辑输入框内容后,通过点击屏幕的其他区域来提交并保存更改。这一功能不仅提升了用户体验,还减少了用户的操作步骤。

实现点击屏幕保存的逻辑

为了实现点击屏幕保存的功能,我们需要在组件中添加一些逻辑和事件处理。以下是一个详细的实现步骤:

1. 设置光标状态:

使用 focusable 属性来控制输入框的焦点状态。
在点击输入框时,将 isShowInput 设置为 true,使其可获得焦点。

.onClick(() => {
  this.isShowInput = true;
})
.focusable(this.isShowInput)

2. 监听全局点击事件

为了检测用户是否点击了屏幕的其他区域,我们需要在父组件的 Column 上监听 onClick 事件。
在父组件的 onClick 事件中,检查 isShowInput 的状态。
如果 isShowInput 为 true,则调用保存逻辑。

Column() {
  TextInput({
    'placeholder': "请输入标题",
    'text': this.idCityTitleModel.title,
  })
    .onClick(() => {
      this.isShowInput = true;
    })
    .onSubmit(async (EnterKeyType) => {
      await this.saveRouteTitle();
    })
    .onChange((value: string) => {
      this.routeTitle = value;
    })
    .focusable(this.isShowInput)
    .cancelButton({
      style: CancelButtonStyle.CONSTANT,
      icon: {
        src: $r('app.media.bond_pen_svg'),
        size: 16,
        color: $r('app.color.menu_font_color')
      }
    })
    .backgroundColor($r('app.color.background_color_lv3'))
    .type(InputType.USER_NAME)
    .fontColor($r("app.color.main_font"))
    .contentType(ContentType.USER_NAME)
    .caretStyle({ width: 1.5, color: '#000000' })
    .textAlign(TextAlign.Start)
    .fontSize(24)
    .width("auto")
    .height(40)
    .borderRadius(5)
    .padding({ right: 5 })
    .margin({ top: 100 })
}
.onClick(async () => {
  if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
    this.isShowInput = false;
    return;
  }
  await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
  this.idCityTitleModel.title = this.routeTitle;
  this.isShowInput = false;
})
.backgroundColor($r("app.color.background_color"))
.width('100%')
.height('100%')

3. 保存用户输入

在父组件的 onClick 事件中,检查 isShowInput 的状态。
如果 isShowInput 为 true,则调用保存逻辑。

private async saveRouteTitle() {
  if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
    this.isShowInput = false;
    return;
  }
  await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
  this.idCityTitleModel.title = this.routeTitle;
  this.isShowInput = false;
}

完整示例代码

import { router } from '@kit.ArkUI'
import { IdCityTitleModel } from '../models/LocationModel'
import { updateRouteNickName } from '../network/api/Route'

@Entry
@Component
export struct Test {
  controller: TextInputController = new TextInputController()
  @State idCityTitleModel: IdCityTitleModel = router.getParams() as IdCityTitleModel
  @State isShowInput: boolean = false;
  routeTitle: string = "";

  private async saveRouteTitle() {
    if (this.idCityTitleModel.title == "" || this.idCityTitleModel.title == this.routeTitle) {
      this.isShowInput = false;
      return;
    }
    await updateRouteNickName(this.idCityTitleModel.routeId, this.routeTitle);
    this.idCityTitleModel.title = this.routeTitle;
    this.isShowInput = false;
  }

  build() {
    Column() {
      TextInput({
        'placeholder': "请输入标题",
        'text': this.idCityTitleModel.title,
      })
        .onClick(() => {
          this.isShowInput = true;
        })
        .onSubmit(async (EnterKeyType) => {
          await this.saveRouteTitle();
        })
        .onChange((value: string) => {
          this.routeTitle = value;
        })
        .focusable(this.isShowInput)
        .cancelButton({
          style: CancelButtonStyle.CONSTANT,
          icon: {
            src: $r('app.media.bond_pen_svg'),
            size: 16,
            color: $r('app.color.menu_font_color')
          }
        })
        .backgroundColor($r('app.color.background_color_lv3'))
        .type(InputType.USER_NAME)
        .fontColor($r("app.color.main_font"))
        .contentType(ContentType.USER_NAME)
        .caretStyle({ width: 1.5, color: '#000000' })
        .textAlign(TextAlign.Start)
        .fontSize(24)
        .width("auto")
        .height(40)
        .borderRadius(5)
        .padding({ right: 5 })
        .margin({ top: 100 })
    }
    .onClick(async () => {
      await this.saveRouteTitle();
    })
    .backgroundColor($r("app.color.background_color"))
    .width('100%')
    .height('100%')
  }
}

解释

  • TextInput 的 onClick 事件:在输入框内点击时,将 isShowInput 设置为 true,使输入框可获得焦点。
  • TextInput 的 onSubmit 事件:通过点击键盘的提交按钮(如“Enter”键)来保存用户输入的内容。
  • 父组件的 onClick 事件:在父组件的 Column 上监听全局点击事件。如果 isShowInput 为 true,则调用 saveRouteTitle 方法来保存用户输入的内容。
  • saveRouteTitle 方法:该方法负责检查用户输入的内容是否为空或与原有内容相同。如果不满足条件,则调用 updateRouteNickName 函数将新标题保存到服务器,并更新本地状态。

取消按钮图标自定义

取消按钮允许用户在编辑输入框内容时取消当前的编辑操作,返回到原始状态。通过自定义取消按钮的样式,可以使界面更加统一和美观。

.cancelButton({
  style: CancelButtonStyle.CONSTANT,
  icon: {
    src: $r('app.media.bond_pen_svg'),
    size: 16,
    color: $r('app.color.menu_font_color')
  }
})

详细请参考我的另一篇博客ArkUI框架下TextInput组件的右侧自定义图标设计指南:提升用户体验的艺术

总结

通过本文的解析,我们不仅了解了 ArkUI 中 TextInput 组件的基本用法和高级特性,还学习了如何提升用户体验和界面美观性。希望这些内容对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言讨论。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2024-12-25 14:07:50修改
1
收藏
回复
举报
回复
    相关推荐