DEV Community

Cover image for HarmonyOS Development: Customize a Dynamic Input Box
程序员一鸣
程序员一鸣

Posted on

HarmonyOS Development: Customize a Dynamic Input Box

Foreword 

this article is based on Api12 

dynamic input boxes are very common, such as Alipay or WeChat. When you send a red envelope or transfer a password, when you enter the previous one, you will automatically switch to the next one. Of course, in addition to the payment password scenario, many verification code input is also realized in this way. It can be said that there are many scenarios used. 

Image description

In the development of Hongmeng, how to achieve this effect, the most important to solve two problems, the first problem is, how to switch the focus to the next input box after the previous input box, the second problem is, how to prohibit the focus of the input box has been input, after the two problems are solved, the other is very simple. 

The outline of this article is as follows: 

1. List of implementation effects

2. Draw the input box

3 How to Switch Focus

4 How to ban focus

5. Open source components are super simple to use

6. Relevant summary


first, to achieve the effect of a list 

the final completion of a component, can be used in any place, I simply wrote a few to achieve the effect, of course, according to the attribute, to achieve a variety of different styles. 

Static effect 

Image description

second, draw the input box

There is nothing to say about the input box, that is, the TextInput component is used. In the actual scene, the number of input boxes is definitely dynamic, so the Grid component is used here to display one row. One of the conveniences of using Grid is to control the distance between columns in addition to the simple configuration of columns. Of course, it is no problem to use other components.

 

Grid() {
      ForEach(this.inputBoxArray, (_: number, index: number) => {
        GridItem() {
          TextInput()
        }
      })
    }.columnsTemplate("1fr ".repeat(this.inputBoxSize).trimEnd())
    .rowsTemplate("1fr")
Enter fullscreen mode Exit fullscreen mode

TextInput component, in addition to the normal style attribute, we need to monitor the change of input content, just through the onChange method, in the onChange method, what we need to do is to store each input content for returning to the business layer, of course, we also need to judge whether there is current content, and if so, then the focus will switch to the next one.

 

if (value != undefined && value != "" && index < this.inputBoxSize) {
                  this.inputBoxTextArray[this.lastPosition] = value //赋值内容
                  this.inputBoxVisibilityArray[this.lastPosition] = false
                  if (index != this.inputBoxSize - 1) {
                    this.lastPosition = index + 1
                    this.inputBoxVisibilityArray[this.lastPosition] = true
                    this.moveFocus(this.lastPosition)
                  } else {
                    this.inputBoxVisibilityArray[this.lastPosition] = false
                  }
                }
Enter fullscreen mode Exit fullscreen mode

How to switch focus 

when drawing TextInput components, each component defines an id, and the focus controller can be used to move the focus to the component with the next id.

 

  /**
   * AUTHOR:AbnerMing
   * INTRODUCE:
   * */
  private moveFocus(index: number) {
    this.getUIContext().getFocusController().requestFocus(this.inputViewIds + index)
  }
Enter fullscreen mode Exit fullscreen mode

How to ban focus 

in the actual development, if we dynamically cancel the focus or prohibit clicking, we will find that the input box cannot be clicked, but there will be the problem that the soft keyboard is folded up and then pops up. In order to solve the problem that multiple input boxes use the same soft keyboard, I use a floating layer here, that is, the input box that has been input is covered with a transparent floating layer, so it cannot be touched. 

Five, open source components super simple to use 

the above is only the idea of implementation. Through this idea, the dynamic input of the input box has been completed and has been submitted to the central warehouse for download. 

https://ohpm.openharmony.cn/#/cn/detail/@abner%2Finput_box

1. Remote Dependency 

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/input_box
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/input_box": "^1.0.0"}
Enter fullscreen mode Exit fullscreen mode

2. Code usage 

  1. Ordinary use  
InputBoxView({
  inputBoxSize: 5,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode
  1. Cursor color  
InputBoxView({
  inputBoxSize: 6,
  caretColor: Color.Red,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode
  1. Border mode  
InputBoxView({
  inputBoxSize: 6,
  caretColor: Color.Red,
  inputBoxBgColor: Color.Transparent,
  inputBoxBorderWidth: 1,
  isInputBoxBorder: true,
  inputBoxNormalBorderColor: Color.Black,
  inputBoxSelectBorderColor: Color.Red,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

4. Display bottom cursor


 

InputBoxView({
  inputBoxSize: 6,
  caretColor: Color.Red,
  inputBoxBgColor: Color.Transparent,
  inputBoxBorderWidth: 1,
  isInputBoxBorder: true,
  isShowBottomCaret: true, //显示底部光标
  inputBoxNormalBorderColor: Color.Black,
  inputBoxSelectBorderColor: Color.Red,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

5. Dot


 

InputBoxView({
  inputBoxSize: 6,
  inputTextType: InputTextType.ROUND,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

6. Asterisk


 

InputBoxView({
  inputBoxSize: 6,
  inputTextType: InputTextType.ASTERISK,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

7. Set border selection color


 

InputBoxView({
  inputBoxSize: 6,
  inputBoxNormalBorderColor: "#e8e8e8",
  inputBoxSelectBorderColor: Color.Blue,
  inputBoxBorderWidth: 1,
  boxInputHideBgColor: true,
  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

8. Set the border underline method


 

InputBoxView({
  inputBoxSize: 6,
  inputBoxBgColor: Color.Transparent,
  inputBoxBorderWidth: { bottom: 2 },
  inputBoxNormalBorderColor: Color.Black,
  inputBoxSelectBorderColor: Color.Black,

  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

9. Set the underline dot mode of the border


 

InputBoxView({
  inputBoxSize: 6,
  inputTextType: InputTextType.ROUND,
  inputBoxBgColor: Color.Transparent,
  inputBoxBorderWidth: { bottom: 2 },
  inputBoxNormalBorderColor: Color.Black,
  inputBoxSelectBorderColor: Color.Black,

  onChange: (value) => {
    console.log("===:" + value)
  },
  onInputEnd: (value) => {
    console.log("===:" + value)
  }
})
Enter fullscreen mode Exit fullscreen mode

3. Property introduction 

property type overview
inputBoxSize  number  number of input boxes, 6 by default 
inputBoxWidth  Length  the width of each input box, which defaults to 100 percent 
inputBoxHeight Length  the height of each input box, which defaults to 100 percent 
inputBoxBgColor  ResourceColor  background of the input box 
inputType  InputType  keyboard type, default is InputType.Number 
inputBoxGap  Length  gap between input boxes, default 10 
inputWidth  Length  the overall width of the input box 
inputHeight  Length  the overall height of the input box 
inputBoxBorderRadius  Length  fillet 
inputBoxBorderWidth  EdgeWidths/Length/LocalizedEdgeWidths  border size 
inputBoxNormalBorderColor  ResourceColor Input box check border background 
inputBoxSelectBorderColor  ResourceColor  border background is not selected in the input box 
inputMarginLeft  Length  the distance to the left of the overall distance of the input box 
inputMarginRight  Length  the distance to the right of the overall distance of the input box 
caretColor  ResourceColor  cursor Color 
boxCaretWidth  Length  cursor width 
inputFontColor  ResourceColor  font Color 
inputFontSize  Length  font Size 
inputFontWeight  umber/FontWeight/string  font Weight 
inputFontStyle FontStyle  font Styles 
fontFamily  ResourceStr  font List 
openRowClick  boolean  open row click 
inputTextType  InputTextType  show Content Type 
boxInputHideBgColor  boolean  whether The Last background is hidden or not is not hidden by default. 
isShowBottomCaret  boolean  whether the cursor displays the bottom, which is not displayed by default. 
isInputBoxBorder  boolean  whether it is a border, the default is not 
onChange  (value: string) => void  input Callback Listener 
onInputEnd  (value: string) => void  end of input 

VI. Relevant Summary

In addition to dynamically switching the focus to the next one, when we click on the soft keyboard to delete, we also need to clear the contents of the input box and switch the focus to the first one. How to monitor the delete button of the soft keyboard can take a lot of effort and execution. Line onKeyEvent event event, found that only the keys of the computer, the soft keyboard of the simulator will not go, think it is the problem of the simulator, switch to the real machine, delete the button will not go. Finally, after continuous investigation, we found that one method is necessary, that is, onWillDelete. When you implement it yourself, you can use this method to avoid detours.

Top comments (0)