
回复
Hey兄弟,今天咱们来聊聊在HarmonyOS里头怎么搞输入法(IME),这可是个技术活儿,但别担心,咱们一步步来。
IME,就是输入法框架,它能让应用和输入法应用之间能聊天,比如你在聊天框里敲字儿,它得把字儿显示出来,这就是IME的活儿。
在HarmonyOS里头,IME Kit提供了两套API,一套是输入法框架API,另一套是输入法服务API。用这些API,你可以自己搞个输入法应用,或者在你自己的应用里头用输入法。
下面是根据文件内容整理的代码实例,咱们一块儿看看。
// 定义键盘按键的数据结构
export interface KeyData {
content: string;
}
// 数字键盘数据
export const numberKeys: KeyData[] = [
{ content: '1' }, { content: '2' }, { content: '3' },
{ content: '4' }, { content: '5' }, { content: '6' },
{ content: '7' }, { content: '8' }, { content: '9' },
{ content: '0' }, { content: '+' }, { content: '-' }
];
// 字母键盘第一行数据
export const letterKeysRow1: KeyData[] = [
{ content: 'Q' }, { content: 'W' }, { content: 'E' },
{ content: 'R' }, { content: 'T' }, { content: 'Y' },
{ content: 'U' }, { content: 'I' }, { content: 'O' },
{ content: 'P' }, { content: '[' }, { content: ']' }
];
// 字母键盘第二行数据
export const letterKeysRow2: KeyData[] = [
{ content: 'A' }, { content: 'S' }, { content: 'D' },
{ content: 'F' }, { content: 'G' }, { content: 'H' },
{ content: 'J' }, { content: 'K' }, { content: 'L' },
{ content: ';' }, { content: "'" }
];
// 字母键盘第三行数据
export const letterKeysRow3: KeyData[] = [
{ content: 'Z' }, { content: 'X' }, { content: 'C' },
{ content: 'V' }, { content: 'B' }, { content: 'N' },
{ content: 'M' }, { content: ',' }, { content: '.' },
{ content: '/' }, { content: '\\' }
];
import { display } from '@kit.ArkUI';
import { inputMethodEngine, InputMethodExtensionContext } from '@kit.IMEKit';
// 获取输入法框架的能力
const inputMethodAbility = inputMethodEngine.getInputMethodAbility();
export class KeyboardController {
private context: InputMethodExtensionContext | undefined;
private panel: inputMethodEngine.Panel | undefined;
private textInputClient: inputMethodEngine.InputClient | undefined;
constructor() {}
// 创建输入法窗口和注册事件监听
public onCreate(context: InputMethodExtensionContext): void {
this.context = context;
this.initWindow();
this.registerListener();
}
// 销毁输入法窗口和注销事件监听
public onDestroy(): void {
this.unRegisterListener();
if (this.panel) {
this.panel.hide();
inputMethodAbility.destroyPanel(this.panel);
}
if (this.context) {
this.context.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.context) return;
let displayInfo = display.getDefaultDisplaySync();
let width = displayInfo.width;
let height = displayInfo.height;
let keyHeightRate = 0.47;
let keyHeight = height * keyHeightRate;
let nonBarPosition = height - keyHeight;
let panelInfo: inputMethodEngine.PanelInfo = {
type: inputMethodEngine.PanelType.SOFT_KEYBOARD,
flag: inputMethodEngine.PanelFlag.FLG_FIXED
};
inputMethodAbility.createPanel(this.context, panelInfo).then((inputPanel: inputMethodEngine.Panel) => {
this.panel = inputPanel;
if (this.panel) {
this.panel.resize(width, keyHeight);
this.panel.moveTo(0, nonBarPosition);
this.panel.setUiContent('InputMethodExtensionAbility/pages/Index');
}
});
}
// 注册事件监听
private registerListener(): void {
this.registerInputListener();
}
// 注册输入法框架服务的监听
private registerInputListener(): void {
inputMethodAbility.on('inputStart', (kbController, textInputClient) => {
this.textInputClient = textInputClient;
});
inputMethodAbility.on('inputStop', () => {
this.onDestroy();
});
}
// 注销事件监听
private unRegisterListener(): void {
inputMethodAbility.off('inputStart');
inputMethodAbility.off('inputStop');
}
}
import { Want } from '@kit.AbilityKit';
import { InputMethodExtensionAbility } from '@kit.IMEKit';
import keyboardController from './model/KeyboardController';
// 输入法服务类,继承自InputMethodExtensionAbility
export default class InputDemoService extends InputMethodExtensionAbility {
// 服务创建时调用
onCreate(want: Want): void {
keyboardController.onCreate(this.context);
}
// 服务销毁时调用
onDestroy(): void {
console.log("onDestroy.");
keyboardController.onDestroy();
}
}
import {
numberSourceListData,
sourceListType,
letterSourceListDataRow1,
letterSourceListDataRow2,
letterSourceListDataRow3
} from './KeyboardKeyData';
import keyboardController from '../model/KeyboardController';
@Component
struct keyItem {
private numberKeyValue: sourceListType = numberSourceListData[0];
@State keyBgc: string = "#fff"
@State keyFontColor: string = "#ff0a0505"
@Styles
pressedStyles(): void {
.backgroundColor("#fff1f0f0")
}
@Styles
normalStyles(): void {
.backgroundColor(Color.White)
}
build() {
Column() {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.Center
}) {
Text(this.numberKeyValue.content).fontSize(20).fontColor(this.keyFontColor)
}
}
.backgroundColor(this.keyBgc)
.borderRadius(6)
.width("8%")
.height("100%")
.onClick(() => {
keyboardController.insertText(this.numberKeyValue.content);
})
.stateStyles({
pressed: this.pressedStyles,
normal: this.normalStyles
})
}
}
// 删除组件
@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 ime_KeysMenu {
private ime_Keys: sourceListType[] = numberSourceListData;
build() {
Row() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly }) {
Flex({ justifyContent: FlexAlign.SpaceBetween }) {
ForEach(this.ime_Keys, (item: sourceListType) => { // 键盘第一行
keyItem({ numberKeyValue: item })
.shadow(0.1)
.borderRadius(102)
}, (item: sourceListType) => item.content);
}
.padding({ top: "2%" })
.width("96%")
// Flex({ justifyContent: FlexAlign.SpaceBetween }) {
// deleteItem()
// }
// .width("96%")
// .height("25%")
}
}
.height(50)
}
}
@Entry
@Component
struct Index {
private numberList: sourceListType[] = numberSourceListData
private letterList1: sourceListType[] = letterSourceListDataRow1;
private letterList2: sourceListType[] = letterSourceListDataRow2;
private letterList3: sourceListType[] = letterSourceListDataRow3;
build() {
Stack() {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.End
}) {
Flex({
direction: FlexDirection.Column,
alignItems: ItemAlign.Center,
justifyContent: FlexAlign.End
}) {
Row() {
Text('林先生制作').fontSize(12) // 将用于整序阁的某一版本
.fontWeight(700)
}
.width('100%')
.backgroundColor(Color.White)
.justifyContent(FlexAlign.Center)
.padding(8)
.borderWidth({ top: 0.25 })
.borderColor('#ffacaaaa')
ime_KeysMenu({
ime_Keys: this.numberList
})
ime_KeysMenu({
ime_Keys: this.letterList1
})
ime_KeysMenu({
ime_Keys: this.letterList2
})
ime_KeysMenu({
ime_Keys: this.letterList3
})
}
.align(Alignment.End)
.width("100%")
.height("100%")
.backgroundColor(Color.White)
}
.height("100%").align(Alignment.End).backgroundColor("#cdd0d7")
}
.position({ x: 0, y: 0 }).zIndex(99999)
}
}
以上就是咱们的输入法IME开发的核心代码,包括键盘数据定义、键盘控制器和输入法服务。这些代码都是根据官方文档和代码文件整理出来的,确保了功能的完整性和准确性。
希望这些代码能帮助你在HarmonyOS上开发出自己的输入法应用。如果有啥问题或者需要进一步的帮助,随时来聊!👍🏻