DEV Community

Cover image for HarmonyOS Development: Customize an English Keyboard
程序员一鸣
程序员一鸣

Posted on

HarmonyOS Development: Customize an English Keyboard

Foreword 

this article is based on Api12 

the series of custom keyboards has been completed one after another. The license plate provinces are referred to as keyboards, the license plate letter selection keyboard and the stock code keyboard are all common keyboards in some special industries. In this article, we will customize an English keyboard for the general public. Like other keyboard definitions, the implementation methods are different due to the different spacing between each line. 

Image description

Code implementation 

in order to better realize the UI effect, a multi-component implementation is also adopted here. After all, the margins of each Row are different. It is divided into four rows for implementation. You can use grid layout or List components for implementation. The Row component I use here uses ForEach to traverse subcomponents in the Row component. Of course, after all, the amount of data is small, which method to use depends on everyone's choice. 

Let's just say that one line of code is implemented, because they are all repeated, except that the data sources and margins displayed are different, and the important thing for each sub-element is its weight.

 

Row() {
        ForEach(["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"], (item: string) => {
          Text(item)
            .layoutWeight(1)
            .height(this.rectHeight)
            .fontSize(this.rectTextSize)
            .fontColor(this.rectTextColor)
            .backgroundColor(this.englishBgColor)
            .textAlign(TextAlign.Center)
            .margin({ left: 5, right: 5 })
            .borderRadius(this.rectBorderRadius)
            .onClick(() => {
              if (this.onItemClick != undefined) {
                this.onItemClick(item)
              }
            })
        })
      }
Enter fullscreen mode Exit fullscreen mode

All codes 

the code is very simple to implement, just look at it yourself.

 

@Component
export struct EnglishKeyboardView {
BgColor: ResourceColor="# f5f5f5"//Background color
English BgColor: ResourceColor="# ffffff"//English background color
OtherBgColor: ResourceColor="# e8e8e8"//Non English background color
RectBorderWidth: Length=1//Grid border width
RectBorderRadius: Length=2//Grid border rounded corners
RectTextCize: Length=16//The text size of the grid
RectTextColor: ResourceColor="# 333333"//Default color for grid text
DeleteIconWidth: Length=30//Delete image width
deleteIconSrc: PixelMap | ResourceStr | DrawableDescriptor = $r("app.media.view_ic_key_delete")
RectHeight: Length=60//Each grid height
MarginTop: Length=10//Distance wise
MarginBottom: Length=10//Below distance
onItemClick? : (item: string)=>void//Click on the item
onDelete? : ()=>void//Click to delete
onComplete? : ()=>void//Click to complete
onChinese? : ()=>void//Chinese
onSpace? : ()=>void//Space
onNumber? : ()=>void//number

build() {
Column() {
Row() {
ForEach(["Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P"], (item: string) => {
Text(item)
.layoutWeight(1)
.height(this.rectHeight)
.fontSize(this.rectTextSize)
.fontColor(this.rectTextColor)
.backgroundColor(this.englishBgColor)
.textAlign(TextAlign.Center)
.margin({ left: 5, right: 5 })
.borderRadius(this.rectBorderRadius)
.onClick(() => {
if (this.onItemClick != undefined) {
this.onItemClick(item)
}
})
})
}

Row() {
ForEach(["A", "S", "D", "F", "G", "H", "J", "K", "L"], (item: string) => {
Text(item)
.layoutWeight(1)
.height(this.rectHeight)
.fontSize(this.rectTextSize)
.fontColor(this.rectTextColor)
.backgroundColor(this.englishBgColor)
.textAlign(TextAlign.Center)
.margin({ left: 5, right: 5 })
.borderRadius(this.rectBorderRadius)
.onClick(() => {
if (this.onItemClick != undefined) {
this.onItemClick(item)
}
})
})
}.margin({ top: 10, left: 20, right: 20 })

Row() {
ForEach (["middle", "Z", "X", "C", "V", "B", "N", "M", "delete"], (item: string, index: number)=>{
if (index == 8) {
Column() {
Image(this.deleteIconSrc)
.width(this.deleteIconWidth)
}
.layoutWeight(1.5)
.justifyContent(FlexAlign.Center)
.backgroundColor(this.otherBgColor)
.height(this.rectHeight)
.onClick(() => {
//Delete
if (this.onDelete != undefined) {
this.onDelete()
}
})
} else {
Text(item)
.layoutWeight(index == 0 ? 1.5 : 1)
.height(this.rectHeight)
.fontSize(this.rectTextSize)
.fontColor(this.rectTextColor)
.backgroundColor((index == 0) ?  this.otherBgColor : this.englishBgColor)
.textAlign(TextAlign.Center)
.margin({ left: 5, right: 5 })
.borderRadius(this.rectBorderRadius)
.onClick(() => {
if (index == 0) {
Chinese
if (this.onChinese != undefined) {
this.onChinese()
}

} else {
if (this.onItemClick != undefined) {
this.onItemClick(item)
}
}
})
}

})
}.margin({ top: 10 })

Row() {
ForEach (["123", "space", "OK"], (item: string, index: number)=>{
Text(item)
.layoutWeight((index == 1) ?  2 : 1)
.height(60)
.backgroundColor(this.otherBgColor)
.textAlign(TextAlign.Center)
.margin({ left: 5, right: 5 })
.borderRadius(this.rectBorderRadius)
.onClick(() => {
if (index == 0) {
//Number
if (this.onNumber != undefined) {
this.onNumber()
}
} else if (index == 1) {
//Space
if (this.onSpace != undefined) {
this.onSpace()
}
} else if (index == 2) {
//Confirm
if (this.onComplete != undefined) {
this.onComplete()
}
}
})
})
}.margin({ top: 10 })
}.backgroundColor(this.bgColor)
.padding({ top: this.marginTop, bottom: this.marginBottom })
}
}
Enter fullscreen mode Exit fullscreen mode

Encapsulation Use 

like the abbreviation of the license plate province, the license plate letters are also packaged for everyone to use. 

Method 1: in the Terminal window, run the following command to install the third-party package. DevEco Studio automatically adds the third-party package dependency to the project oh-package.json5. 

Suggestion: Execute the command under the module path used.


ohpm install @abner/keyboard
Enter fullscreen mode Exit fullscreen mode

Method 2: Set the three-party package dependency in the project oh-package.json5. The configuration example is as follows:

"dependencies": { "@abner/keyboard": "^1.0.0"}
Enter fullscreen mode Exit fullscreen mode

Code call


 

EnglishKeyboardView({
onItemClick: (item: string) => {
//Click on the event
Console.log ("====Click on content:"+item)
},
onDelete: () => {
//Click to delete
Console.log ("====Click to delete")
},
onComplete: () => {
//Click OK
Console.log ("====Click OK")
},
onChinese: () => {
//Click on Chinese to switch
Console.log ("====Click on Chinese to switch")
},
onSpace: () => {
//Click on the space
Console.log ("====Click on Space")
},
onNumber: () => {
//Click on the number
Console.log ("====Click on number")
}
})
Enter fullscreen mode Exit fullscreen mode

property Introduction


property type overview
onItemClick  (item: string) => void  click entry callback 
onDelete  () => void  click Delete Callback 
onComplete  () => void  click Finish Callback 
onChinese  () => void  click Chinese callback 
onSpace  () => void  click Space Callback 
onNumber  () => void  click Digital Callback 
bgColor  ResourceColor  background Color 
englishBgColor  ResourceColor  english background color
otherBgColor  ResourceColor  non-English background color 
rectBorderWidth  Length  grid Border Width 
rectBorderRadius  Length  check Border Fillet 
rectTextSize  Length  text size of grid 
rectTextColor  ResourceColor  default color for check text 
deleteIconWidth  Length  delete icon width 
deleteIconSrc  PixelMap /ResourceStr /DrawableDescriptor  delete icon resources 
rectHeight  Length  height of each grid 
marginTop  Length  distance from top
marginBottom  Length  distance from below 

related Summary 

there are many ways to implement it. At present, a relatively simple one is adopted. If you adopt the Grid Grid component implementation method, it is also possible, but you need to consider the margin and data of each row, as well as the Grid Occupancy problem of the last two rows.

Top comments (0)