HarmonyOS应用开发:Webview拉起自定义键盘

场景描述

在特殊的H5场景下需要应用拉起自定义键盘进行输入。

场景一:使用jsBridge拉起自定义弹窗写自定义键盘,再通过jsBridge传参实现输入。

场景二:使用web的同层渲染将原生textInput组件渲染到页面上。

方案描述

通过注册一个js代理对象被web的registerJavaScriptProxy方法调用拉起CustomDialog,在CustomDialog上放置一个customkeyboard

场景一:通过jsBridge拉起自定义弹窗,在自定义弹窗上放置自定义键盘,例如需要输入密码时的安全键盘。

效果图

方案

通过注册一个js代理对象被web的registJavaScriptProxy方法调用拉起CustomDialog,在CustomDialog上放置一个自定义键盘组件,通过在H5上input标签的readonly属性和注册的js方法changeNumbers实现在原生端输入数字传到H5上,他们之间通过@Link装饰器绑定的变量进行传值,所以点击删除输入的内容也是可以在H5上实现的。

核心代码

通过javaScriptProxy方法拉起自定义弹窗,在H5上的input标签绑定一个onclick事件,当点击输入框后会调用从原生注册过来的js代理方法openWindow。

typescript 复制代码
<input type="text" name="number_info" readonly onclick="openWindow()" value="" style="width: 500px;height: 100px;font-size:50px;border:1px solid # f00;">
 
<script>
 
function openWindow() {
 
let value = document.getElementsByName("number_info")[0].value;
 
window.myJsb.openDialog(value)
 
}
 
</script>

当H5上openWindow方法被调用后会通过jsBridge调用以下两个js代理方法打开自定义弹窗。

kotlin 复制代码
jsbObject: JsbObject = {
 
openDialog: (value: string) => {
 
this.showDialog(this, value);
 
}
 
}
 
showDialog(context: object, value: string) {
 
// 把自定义弹窗调出来
 
this.currentData = value;
 
this.dialogController.open()
 
}
 
 
 
Web({ src: "resource://rawfile/web_test.html", controller: this.webviewController })
 
.javaScriptAccess(true)
 
.javaScriptProxy({
 
name: "myJsb",
 
object: this.jsbObject,
 
methodList: ["openDialog"],
 
controller: this.webviewController
 
}

将自定义键盘放置在自定义弹窗上。

scss 复制代码
@CustomDialog
 
struct CustomDialogExample {
 
@Link currentData: string
 
dialogControllerTwo: CustomDialogController | null = new CustomDialogController({
 
builder: CustomDialogExample({ currentData: $currentData }),
 
alignment: DialogAlignment.Bottom,
 
offset: { dx: 0, dy: -25 }
 
})
 
controller?: CustomDialogController
 
 
 
build() {
 
Column() {
 
Button('x').onClick(() => {
 
// 关闭自定义键盘
 
if (this.controller != undefined) {
 
this.controller.close()
 
}
 
})
 
Grid() {
 
ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '删除'], (item: number | string) => {
 
GridItem() {
 
Button(item + "")
 
.width(110).onClick(() => {
 
if (item == '删除') {
 
if (this.currentData.length > 0) {
 
this.currentData = this.currentData.substring(0, this.currentData.length - 1);
 
}
 
} else {
 
this.currentData += item
 
}
 
})
 
}
 
})
 
}.maxCount(3).columnsGap(10).rowsGap(10).padding(5)
 
}.backgroundColor(Color.Gray)
 
}
 
}

在自定义键盘上输入内容的时候会调用onChangeInputValue方法,通过里面的runJavaScript调用H5上的js方法changeNumber传值到H5的输入框中。

typescript 复制代码
onChangeInputValue(stateName: string){
 
console.log('this.currentData:' + this.currentData)
 
this.webviewController.runJavaScript('changeNumber("'+ this.currentData +'")')
 
.then((result) => {
 
console.log('result: ' + result);
 
})
 
}
 
 
<<input type="text" name="number_info" readonly onclick="openWindow()" value="" style="width: 500px;height: 100px;font-size:50px;border:1px solid # f00;" />
 
<script>
 
function changeNumber(value){
 
document.getElementsByName("number_info")[0].value = value;
 
}
 
</script>

**场景二:**通过同层渲染渲染一个原生的自定义键盘

效果图

方案

整体实现效果为:通过web的同层渲染功能实现将原生TextInput组件渲染到H5需要使用自定义键盘的页面中,这样就可以实现在H5拉起自定义键盘,并且使用它的全部功能。

核心代码

  1. 创建一个自定义键盘并绑定到原生textInput组件上。

    @Component

    struct ButtonComponent {

    controller1: TextInputController = new TextInputController()

    @State inputValue: string = ""

    // 自定义键盘组件

    @Builder

    CustomKeyboardBuilder() {

    Column() {

    Button('x').onClick(() => {

    // 关闭自定义键盘

    this.controller1.stopEditing()

    })

    Grid() {

    ForEach([1, 2, 3, 4, 5, 6, 7, 8, 9, '*', 0, '# '], (item: number | string) => {

    GridItem() {

    Button(item + "")

    .width(110).onClick(() => {

    this.inputValue += item

    })

    }

    })

    }.maxCount(3).columnsGap(10).rowsGap(10).padding(5)

    }.backgroundColor(Color.Pink)

    }

    @ObjectLink params: Params

    @State bkColor: Color = Color.Red

    @State outSetValueTwo: number = 40

    @State outSetValueOne: number = 40

    @State tipsValue: number = 40

    controller: web_webview.WebviewController = new web_webview.WebviewController();

    build() {

    Column() {

    TextInput({ controller: this.controller1, text: this.inputValue })// 绑定自定义键盘

    .customKeyboard(this.CustomKeyboardBuilder()).margin(10).border({ width: 1 })

    }

    .width(this.params.width)

    .height(this.params.height)

    }

    }

将原生textInput组件通过web同层渲染功能渲染到H5上的embed标签上。

如果您想系统深入地学习 HarmonyOS 开发或想考取HarmonyOS认证证书,欢迎加入华为开发者学堂:

请点击→: HarmonyOS官方认证培训

相关推荐
低调小一6 小时前
深度复盘:KMP 在字节跳动的工程化落地实践
android·kotlin
编程乐学7 小时前
鸿蒙非原创--DevEcoStudio开发的奶茶点餐APP
华为·harmonyos·deveco studio·鸿蒙开发·奶茶点餐·鸿蒙大作业
鸣弦artha7 小时前
Flutter框架跨平台鸿蒙开发 —— Text Widget:文本展示的艺术
flutter·华为·harmonyos
lili-felicity9 小时前
React Native for Harmony:Rating 评分组件- 支持全星 / 半星 / 禁用 / 自定义样式
react native·华为·harmonyos
grd49 小时前
RN for OpenHarmony 小工具 App 实战:屏幕尺子实现
笔记·harmonyos
No Silver Bullet9 小时前
HarmonyOS NEXT开发进阶(十九):如何在 DevEco Studio 中查看已安装应用的运行日志
华为·harmonyos
歪楼小能手9 小时前
Android16系统go版关闭重力旋转开关后缺失手动旋转屏幕悬浮按钮
android·java·平板
崇山峻岭之间9 小时前
Matlab学习记录37
android·学习·matlab
大雷神10 小时前
HarmonyOS智慧农业管理应用开发教程--高高种地
华为·harmonyos
南村群童欺我老无力.11 小时前
Flutter 框架跨平台鸿蒙开发 - 开发双人对战五子棋游戏
flutter·游戏·华为·typescript·harmonyos