赞
踩
IME Kit提供输入法框架和输入法服务两类API。用于实现输入法应用,也可以用于实现自绘编辑框以及实现对输入法应用的控制。
输入法应用:
支持创建固定态、悬浮态和状态栏三种类型的Panel,可支持开发一个输入法应用同时部署在手机、平板多设备中。
自定义编辑框:
支持开发者自定义编辑框,实现绑定输入法应用,并实现输入法应用的文输入、删除、选中、光标移动等操作。
提供输入法服务相关API,用于输入法应用,包括:创建软键盘窗口、插入/删除字符、选中文本、监听物理键盘按键事件等;
提供输入法框架相关API,可用于自绘编辑框,包括绑定输入法,实现输入、删除、选中、光标移动等。
提供系统应用管理输入法应用能力,实现对输入法应用的控制,包括显示/隐藏输入法软键盘、切换输入法、获取所有输入法列表。
ArkUI: IME Kit在输入法软键盘和自绘编辑框时使用ArkUI提供的部分组件、事件、动效、状态管理等能力,例如Text、Button组件,onClick点击事件。
onCreate()
服务被首次创建时触发该回调,开发者可以在此进行一些初始化的操作,例如注册公共事件监听等。
说明
如果服务已创建,再次启动该InputMethodExtensionAbility不会触发onCreate()回调。
onDestroy()
当不再使用服务且准备将该实例销毁时,触发该回调。开发者可以在该回调中清理资源,如注销监听等。
开发者在实现一个输入法应用时,需要在DevEco Studio工程中新建一个InputMethodExtensionAbility,具体步骤如下:
在工程Module对应的ets目录下,右键选择“New > Directory”,新建一个目录,并命名为InputMethodExtensionAbility。
在InputMethodExtensionAbility目录下,右键选择“New > File”,新建四个文件,分别为KeyboardController.ts、InputMethodService.ts、Index.ets以及KeyboardKeyData.ts。目录如下:
- /src/main/
- ├── ets/InputMethodExtensionAbility
- │ └──model/KeyboardController.ts # 显示键盘
- │ └──InputMethodService.ts # 自定义类继承InputMethodExtensionAbility并加上需要的生命周期回调
- │ └──pages
- │ └── Index.ets # 绘制键盘,添加输入删除功能
- │ └── KeyboardKeyData.ts # 键盘属性定义
- ├── resources/base/profile/main_pages.json
InputMethodService.ts文件。
在InputMethodService.ts文件中,增加导入InputMethodExtensionAbility的依赖包,自定义类继承InputMethodExtensionAbility并加上需要的生命周期回调。
- import { Want } from '@kit.AbilityKit';
- import keyboardController from './model/KeyboardController';
- import { InputMethodExtensionAbility } from '@kit.IMEKit';
-
- export default class InputDemoService extends InputMethodExtensionAbility {
-
- onCreate(want: Want): void {
- keyboardController.onCreate(this.context); // 初始化窗口并注册对输入法框架的事件监听
- }
-
- onDestroy(): void {
- console.log("onDestroy.");
- keyboardController.onDestroy(); // 销毁窗口并去注册事件监听
- }
- }
KeyboardController.ts文件。
- import { common } from '@kit.AbilityKit';
- import { display } from '@kit.ArkUI';
- import { inputMethodEngine, InputMethodExtensionContext } from '@kit.IMEKit';
-
- // 调用输入法框架的getInputMethodAbility方法获取实例,并由此实例调用输入法框架功能接口
- const inputMethodAbility: inputMethodEngine.InputMethodAbility = inputMethodEngine.getInputMethodAbility();
-
- export class KeyboardController {
- private mContext: InputMethodExtensionContext | undefined = undefined; // 保存InputMethodExtensionAbility中的context属性
- private panel: inputMethodEngine.Panel | undefined = undefined;
- private textInputClient: inputMethodEngine.InputClient | undefined = undefined;
- private keyboardController: inputMethodEngine.KeyboardController | undefined = undefined;
-
- constructor() {
- }
-
- public onCreate(context: InputMethodExtensionContext): void
- {
- this.mContext = context;
- this.initWindow(); // 初始化窗口
- this.registerListener(); // 注册对输入法框架的事件监听
- }
-
- public onDestroy(): void // 应用生命周期销毁
- {
- this.unRegisterListener(); // 去注册事件监听
- if(this.panel) { // 销毁窗口
- this.panel.hide();
- inputMethodAbility.destroyPanel(this.panel);
- }
- if(this.mContext) {
- this.mContext.destroy();
- }
- }
-
- public insertText(text: string): void {
- if(this.textInputClient) {
- this.textInputClient.insertText(text);
- }
- }
-
- public deleteForward(length: number): void {
- if(this.textInputClient) {
- this.textInputClient.deleteForward(length);
- }
- }
-
- private initWindow(): void // 初始化窗口
- {
- if(this.mContext === undefined) {
- return;
- }
- let dis = display.getDefaultDisplaySync();
- let dWidth = dis.width;
- let dHeight = dis.height;
- let keyHeightRate = 0.47;
- let keyHeight = dHeight * keyHeightRate;
- let nonBarPosition = dHeight - keyHeight;
- let panelInfo: inputMethodEngine.PanelInfo = {
- type: inputMethodEngine.PanelType.SOFT_KEYBOARD,
- flag: inputMethodEngine.PanelFlag.FLG_FIXED
- };
- inputMethodAbility.createPanel(this.mContext, panelInfo).then(async (inputPanel: inputMethodEngine.Panel) => {
- this.panel = inputPanel;
- if(this.panel) {
- await this.panel.resize(dWidth, keyHeight);
- await this.panel.moveTo(0, nonBarPosition);
- await this.panel.setUiContent('inputmethodextability/pages/Index');
- }
- });
- }
-
- private registerListener(): void
- {
- this.registerInputListener(); // 注册对输入法框架服务的监听
- // 注册隐藏键盘事件监听等
- }
-
- private registerInputListener(): void { // 注册对输入法框架服务的开启及停止事件监听
- inputMethodAbility.on('inputStart', (kbController, textInputClient) => {
- this.textInputClient = textInputClient; // 此为输入法客户端实例,由此调用输入法框架提供给输入法应用的功能接口
- this.keyboardController = kbController;
- })
- inputMethodAbility.on('inputStop', () => {
- this.onDestroy(); // 销毁KeyboardController
- });
- }
-
- private unRegisterListener(): void
- {
- inputMethodAbility.off('inputStart');
- inputMethodAbility.off('inputStop', () => {});
- }
- }
-
- const keyboardController = new KeyboardController();
-
- export default keyboardController;

KeyboardKeyData.ts文件。
定义软键盘的按键显示内容。
- export interface sourceListType {
- content: string,
- }
-
- export let numberSourceListData: sourceListType[] = [
- {
- content: '1'
- },
- {
- content: '2'
- },
- {
- content: '3'
- },
- {
- content: '4'
- },
- {
- content: '5'
- },
- {
- content: '6'
- },
- {
- content: '7'
- },
- {
- content: '8'
- },
- {
- content: '9'
- },
- {
- content: '0'
- }
- ]

Index.ets文件。
主要描绘了具体按键功能。如按下数字键,就会将数字内容在输入框中打印出来,按下删除键,就会将内容删除。
同时在resources/base/profile/main_pages.json文件的src字段中添加此文件路径。
- import { numberSourceListData, sourceListType } from './keyboardKeyData';
- import keyboardController from '../InputMethodExtensionAbility/model/KeyboardController';
-
- @Component
- struct keyItem {
- private keyValue: sourceListType = numberSourceListData[0];
- @State keyBgc: string = "#fff"
- @State keyFontColor: string = "#000"
-
- build() {
- Column() {
- Flex({ direction: FlexDirection.Column,
- alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
- Text(this.keyValue.content).fontSize(20).fontColor(this.keyFontColor)
- }
- }
- .backgroundColor(this.keyBgc)
- .borderRadius(6)
- .width("8%")
- .height("65%")
- .onClick(() => {
- keyboardController.insertText(this.keyValue.content);
- })
- }
- }
-
- // 删除组件
- @Component
- export struct deleteItem {
- @State keyBgc: string = "#fff"
- @State keyFontColor: string = "#000"
-
- build() {
- Column() {
- Flex({ direction: FlexDirection.Column,
- alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
- Text("删除").fontSize(20).fontColor(this.keyFontColor)
- }
- }
- .backgroundColor(this.keyBgc)
- .width("13%")
- .borderRadius(6)
- .onClick(() => {
- keyboardController.deleteForward(1);
- })
- }
- }
-
- // 数字键盘
- @Component
- struct numberMenu {
- private numberList: sourceListType[] = numberSourceListData;
-
- build() {
- Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) {
- Flex({ justifyContent: FlexAlign.SpaceBetween }) {
- ForEach(this.numberList, (item: sourceListType) => { // 数字键盘第一行
- keyItem({ keyValue: item })
- }, (item: sourceListType) => item.content);
- }
- .padding({ top: "2%" })
- .width("96%")
- .height("25%")
-
- Flex({ justifyContent: FlexAlign.SpaceBetween }) {
- deleteItem()
- }
- .width("96%")
- .height("25%")
- }
- }
- }
-
- @Entry
- @Component
- struct Index {
- private numberList: sourceListType[] = numberSourceListData
-
- build() {
- Stack() {
- Flex({
- direction: FlexDirection.Column,
- alignItems: ItemAlign.Center,
- justifyContent: FlexAlign.End
- }) {
- Flex({
- direction: FlexDirection.Column,
- alignItems: ItemAlign.Center,
- justifyContent: FlexAlign.SpaceBetween
- }) {
- numberMenu({
- numberList: this.numberList
- })
- }
- .align(Alignment.End)
- .width("100%")
- .height("75%")
- }
- .height("100%").align(Alignment.End).backgroundColor("#cdd0d7")
- }
- .position({ x: 0, y: 0 }).zIndex(99999)
- }
- }

在工程Module对应的module.json5配置文件module.json5配置文件module.json5配置文件中注册InputMethodExtensionAbility,type标签需要设置为“inputMethod”,srcEntry标签表示当前InputMethodExtensionAbility组件所对应的代码路径。
- {
- "module": {
- ...
- "extensionAbilities": [
- {
- "description": "inputMethod",
- "icon": "$media:icon",
- "name": "InputMethodExtAbility",
- "srcEntry": "./ets/InputMethodExtensionAbility/InputMethodService.ts",
- "type": "inputMethod",
- "exported": true,
- }
- ]
- }
- }
- import { inputMethod } from '@kit.IMEKit';
- import { BusinessError } from '@kit.BasicServicesKit';
-
- let inputMethodSetting = inputMethod.getSetting();
- try {
- inputMethodSetting.showOptionalInputMethods((err: BusinessError, data: boolean) => {
- if (err) {
- console.error(`Failed to showOptionalInputMethods: ${JSON.stringify(err)}`);
- return;
- }
- console.log('Succeeded in showing optionalInputMethods.');
- });
- } catch (err) {
- console.error(`Failed to showOptionalInputMethods: ${JSON.stringify(err)}`);
- }
在弹窗上显示的输入法应用列表中,选择并点击demo应用,将demo应用切换为当前输入法。
点击任意编辑框,即可拉起输入法demo。
为了降低InputMethodExtensionAbility能力被三方应用滥用的风险,在InputMethodExtensionAbility中限制调用以下模块中的接口。
开发者在实现一个自绘编辑框控件时,需要在在DevEco Studio工程中新建一个ets文件,命名为自定义控件的名称,本示例中命名为CustomInput,在文件中定义一个自定义控件,并从@kit.IMEKit中导入inputMethod。
- import { inputMethod } from '@kit.IMEKit';
-
- @Component
- export struct CustomInput {
- build() {
- }
- }
在控件中,使用Text组件作为自会编辑框的文本显示组件,使用状态变量inputText作为Text组件要显示的内容。
- import { inputMethod } from '@kit.IMEKit';
-
- @Component
- export struct CustomInput {
- @State inputText: string = ''; // inputText作为Text组件要显示的内容。
-
- build() {
- Text(this.inputText) // Text组件作为自会编辑框的文本显示组件。
- .fontSize(16)
- .width('100%')
- .lineHeight(40)
- .id('customInput')
- .height(45)
- .border({ color: '#554455', radius: 30, width: 1 })
- .maxLines(1)
- }
- }

在控件中获取inputMethodController实例,并在文本点击时调用controller示例的attach方法绑定和拉起软键盘,并注册监听输入法插入文本、删除等方法,本示例仅展示插入、删除。
- import { inputMethod } from '@kit.IMEKit';
-
- @Component
- export struct CustomInput {
- @State inputText: string = ''; // inputText作为Text组件要显示的内容。
- private inputController: inputMethod.InputMethodController = inputMethod.getController();
-
- build() {
- Text(this.inputText) // Text组件作为自会编辑框的文本显示组件。
- .fontSize(16)
- .width('100%')
- .lineHeight(40)
- .id('customInput')
- .height(45)
- .border({ color: '#554455', radius: 30, width: 1 })
- .maxLines(1)
- .onClick(()=>{
- this.attachAndListener(); // 点击控件
- })
- }
-
- async attachAndListener() { // 绑定和设置监听
- focusControl.requestFocus('CustomInput');
- await this.inputController.attach(true, {
- inputAttribute: {
- textInputType: inputMethod.TextInputType.TEXT,
- enterKeyType: inputMethod.EnterKeyType.SEARCH
- }
- });
- this.inputController.on('insertText', (text) => {
- this.inputText += text;
- })
- this.inputController.on('deleteLeft', (length) => {
- this.inputText = this.inputText.substring(0, this.inputText.length - length);
- })
- }
- }

在应用界面布局中引入该控件即可,此处假设使用界面为Index.ets和控件CustomInput.ets在同一目录下。
有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。
点击领取→【纯血版鸿蒙全套最新学习资料】(安全链接,放心点击)
这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、(南向驱动、嵌入式等)鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!
鸿蒙(HarmonyOS NEXT)最新学习路线
有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。
获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料
HarmonyOS Next 最新全套视频教程
《鸿蒙 (OpenHarmony)开发基础到实战手册》
OpenHarmony北向、南向开发环境搭建
《鸿蒙开发基础》
《鸿蒙开发进阶》
《鸿蒙进阶实战》
大厂面试必问面试题
鸿蒙南向开发技术
鸿蒙APP开发必备
鸿蒙生态应用开发白皮书V2.0PDF
总结
总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。