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.
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
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")
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
}
}
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)
}
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
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"}
2. Code usage
- Ordinary use
InputBoxView({
inputBoxSize: 5,
onChange: (value) => {
console.log("===:" + value)
},
onInputEnd: (value) => {
console.log("===:" + value)
}
})
- Cursor color
InputBoxView({
inputBoxSize: 6,
caretColor: Color.Red,
onChange: (value) => {
console.log("===:" + value)
},
onInputEnd: (value) => {
console.log("===:" + value)
}
})
- 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)
}
})
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)
}
})
5. Dot
InputBoxView({
inputBoxSize: 6,
inputTextType: InputTextType.ROUND,
onChange: (value) => {
console.log("===:" + value)
},
onInputEnd: (value) => {
console.log("===:" + value)
}
})
6. Asterisk
InputBoxView({
inputBoxSize: 6,
inputTextType: InputTextType.ASTERISK,
onChange: (value) => {
console.log("===:" + value)
},
onInputEnd: (value) => {
console.log("===:" + value)
}
})
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)
}
})
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)
}
})
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)
}
})
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)