在HarmonyOS Next开发中实现自定义键盘 原创

youlanjihua
发布于 2025-3-24 09:26
浏览
0收藏

大家好,今天要和大家分享的是在鸿蒙开发中实现自定义键盘。

在HarmonyOS Next开发中实现自定义键盘-鸿蒙开发者社区

接触鸿蒙开发时间越长,越感觉到它的人性化和便利性,像自定义键盘这种在其他平台极具难度和复杂性的事情,在鸿蒙开发中只需要一句代码就能实现。

只需要在TextInput的customKeyboard属性传入自己的键盘组件,就能替换掉系统的键盘,简直不要太方便:

TextInput({ controller: this.controller, text: this.inputValue })

  .customKeyboard(this.CustomKeyboardBuilder())
  • 1.
  • 2.
  • 3.

所以接下来的工作就只有搭建自己的键盘样式,看似只是简单的按钮排列,其实有不少的坑要踩。

首先做一个字母键盘,排列布局方式大家随心所欲,只要能实现就好,我这里就使用最简单的方式,Column和Row的组合使用,简单结构如下:

Column({space:8}){
  Row(){
    //q、w、e、r。。。
  }
  Row(){
    //a、s、d。。。
  }
  Row(){
    //z、x、c。。。
  }
  Row(){
    //空格。。。
  }
}
.padding({top:20,bottom:20})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

其中最后两行有些特殊尺寸的按键需要单独计算,算术问题这里不再赘述。

接下来要为键盘添加一些样式,比如阴影:

.shadow({
  offsetX:0,
  offsetY:5,
  color:Color.Black,
  radius:3
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

还要实现按压的效果,stateStyles属性可以设置组件在不同状态下的样式:

.stateStyles({ normal: {.backgroundColor(this.backColor)}, pressed: {.backgroundColor($r('app.color.state_styles_pressed'))}})
  • 1.

这样字母键盘的页面就做好了。接下来要为按键添加点击事件,也就是点击的时候将按键上的内容传回即可,通常来说使用onClick就可以实现,但是还可以再完美一点。

因为键盘中的删除按钮长按的话应该要有一个持续的删除效果,这样的话简单的使用onClick就无法满足要求。所以这里要使用组合手势,既要识别单击也要识别长按:

.gesture(

  GestureGroup(GestureMode.Parallel,

    TapGesture({ count: 1 })

      .onAction(() => {

        console.log('点击事件')

        this.clickAction()

      }),

    LongPressGesture({ repeat: true })

      .onAction((event: GestureEvent|undefined) => {

        if(event){

          if (event.repeat) {

          }

        }

        console.info('长按事件');

        if(this.longClickAction){

          this.longClickAction()

        }

      })

  )
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.

这里使用的是并行组合手势,互不影响。

然后要实现大小写的转换,比较简单,大写是toUpperCase(),小写就是toLowerCase()。

最后实现删除功能,无论是单击还是长按都删除输入框内容的最后一个字符,长按事件会持续调用,这里不用理会:

this.inputValue  = this.inputValue.slice(0,-1);

  • 1.
  • 2.

这样一个纯字母键盘就基本实现了,接下来再开发一个数字键盘,数字键盘看起来布局就比较简单,所有按键大小一致。

在HarmonyOS Next开发中实现自定义键盘-鸿蒙开发者社区

那这里能不能使用Grid?布局肯定是可以实现,而且是最简单快捷的方式,但是我发现stateStyles的按压效果在

Grid组件中不能及时响应,会顿一下,这个暂时不去研究,换一种布局方式就好了,还是采用跟字母键盘一样的组合布局方式。

最后再实现字母键盘和数字键盘的点击切换,一个非常好看的自定义键盘就实现了。

现在回过头去,对代码做一些优化。既然所有的按键都有阴影,都有点击事件,我们就把封装一下:

@Component

export struct KeyBoardPack{

  @Prop packWidth:number

  @Prop packHeight:number

  @Prop backColor:string = '#ffffff'

  @Builder customBuilder() {};

  @BuilderParam customBuilderParam: () => void = this.customBuilder;

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

  longClickAction?:()=>void=()=>{}

  @Styles

  pressedStyles() {

    .backgroundColor($r('app.color.state_styles_pressed'))

  }

  @Styles

  normalStyles() {

    .backgroundColor(Color.White)

  }

  build() {

    Row(){

      this.customBuilderParam()

    }

    .justifyContent(FlexAlign.Center)

    .width(this.packWidth)

    .height(this.packHeight)

    .shadow({

      offsetX:0,

      offsetY:5,

      color:Color.Black,

      radius:3

    })

    .stateStyles({ normal: {.backgroundColor(this.backColor)}, pressed: {.backgroundColor($r('app.color.state_styles_pressed'))}})

    .gesture(

      GestureGroup(GestureMode.Parallel,

        TapGesture({ count: 1 })

          .onAction(() => {

            console.log('点击事件')

            this.clickAction()

          }),

        LongPressGesture({ repeat: true })

          .onAction((event: GestureEvent|undefined) => {

            if(event){

              if (event.repeat) {

              }

            }

            console.info('长按事件');

            if(this.longClickAction){

              this.longClickAction()

            }

          })

      )

    )

  }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.

这样再添加按键的时候就直接使用封装好的组件:

KeyBoardPack({packWidth:this.keyItemWidth,packHeight:this.keyItemHeight,clickAction:()=>{

  this.keyInputAction(KeyBoardType.normal,this.Upper?item.toUpperCase():item.toLowerCase())

}}){

  Text(this.Upper?item.toUpperCase():item.toLowerCase())

    .fontColor(Color.Black)

    .fontSize(15)

    .fontWeight(FontWeight.Bold)

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

以上就是今天的案例分享,感谢阅读。本文项目源码地址:

https://gitee.com/the-blue-plan/cuskeyboard
  • 1.

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2025-3-24 09:27:57修改
收藏
回复
举报
回复
    相关推荐