鸿蒙开发实践1:自定义一个带删除功能的输入框

440 阅读3分钟

前言

随着鸿蒙next越来越近,鸿蒙开发也逐渐进入程序员的视野,为了紧跟‘时尚前沿’,以及公司业务需求,笔者也开始学习使用ArkTS进行鸿蒙应用的开发。

在绘制登录页面的时候,因为需要一个带删除按钮的输入框,所以笔者尝试着自定义输入框组件,中间也踩了很多坑,于是决定记录下来,希望能够给广大程序员提供一些帮助。

创建自定义组件

首先我们创建一个.ets后缀的文件,然后搭建初步的框架

@Component
export default struct ClearTextInput {
}

这里需要注意的是export default 前缀,寓意为默认导出的组件名,失去export关键词则无法在其他文件中调用该组件。

组件页面的布局很简单,这里略过不谈,下面是组件代码:

//带有清除按钮的输入框
@Component
export default struct ClearTextInput {
  private placeholder?: Resource
  @Link text: string
  @State isEditing: boolean = false
  private fontSize: Length = 15
  private inputType:InputType = InputType.Normal

  build() {
    Row() {
      TextInput({ text: this.text, placeholder: this.placeholder })
        .onChange((value: string) => {
          this.text = value
        })
        .layoutWeight(1)
        .height('100%')
        .caretColor($r('app.color.red'))
        .fontSize(this.fontSize)
        .backgroundColor('#ffffff')
        .onEditChange((isEditing) => {
          this.isEditing = isEditing
        })
        .type(this.inputType)
        .padding(0)
        .placeholderFont({ size: this.fontSize })
        .margin({ right: -20 })
      Image($r('app.media.cross')).width(20).onClick(() => {
        this.text = ''
      }).visibility(this.text != '' && this.isEditing ? Visibility.Visible : Visibility.None)
    }.width('100%').height('100%').align(Alignment.End)
  }
}

这里最需要注意的是两个地方,分别是@State@Link,其中@State表示当数据刷新时,该变量影响到的页面也会刷新。而@Link则表示父子组件变量双向绑定,当子组件变量发生变化时,父组件传进来的变量也会发生变化。

使用自定义组件

写完自定义组件后,我们就需要在父组件中进行使用,首先是引入

import ClearTextInput from './components/ClearTextInput'

使用也很简单

ClearTextInput({
  text: this.username,
  fontSize: 15,
  placeholder: '用户名'
})

但是这里还有一个坑,因为笔者需要判定是否输入完毕来使登录按钮变成可点击的状态,所以需要对输入框的输入状态进行监听,每次输入完毕后调用状态更新的函数。

这就需要我们在子组件的TextInputonChange方法中去调用登录按钮状态更新的函数,本来笔者想把匿名函数作为传参传到子组件中,在onChange方法中调用匿名函数,类似下方的效果

confirm: () => void = () => {
}

但是笔者很快发现子组件中调用不到父组件中的变量,导致状态更新函数无法生效。就在笔者一筹莫展的时候,突然发现了一个东西,那就是@Watch注释,该注释会在变量发生变化时,调用注释后的函数,具体的使用方式如下:

@State @Watch('setLoginButtonState') username: string = ''

通过这种方式,当子组件中变量发生改变,通过@Link传到父组件的username,当@Watch监听到变量username发生改变,于是调用括号中的setLoginButtonState函数,最后导致登录按钮状态发生更新,一条完整的逻辑链就此达成!至此,自定义的输入框组件已经没有任何问题了。

总结

ArtTS作为一门新的语言,许多功能的实现都有不少坑,所以笔者将其记录下来,希望能够给需要的朋友提供一点帮助。