回复
IME Kit ——打造专属输入法,让用户的输入独具风味(1) 原创
因为活着就一定行
发布于 2024-11-28 10:42
浏览
0收藏
搞懂IME:HarmonyOS输入法开发指南
Hey兄弟,今天咱们来聊聊在HarmonyOS里头怎么搞输入法(IME),这可是个技术活儿,但别担心,咱们一步步来。
IME是啥玩意儿?
IME,就是输入法框架,它能让应用和输入法应用之间能聊天,比如你在聊天框里敲字儿,它得把字儿显示出来,这就是IME的活儿。
怎么做?
在HarmonyOS里头,IME Kit提供了两套API,一套是输入法框架API,另一套是输入法服务API。用这些API,你可以自己搞个输入法应用,或者在你自己的应用里头用输入法。
8种应用场景
- 固定面板输入法:就像你手机屏幕上那个键盘,固定在那儿,你敲啥它显示啥。
- 悬浮面板输入法:这个能到处飘,你想在哪儿输入就飘到哪儿。
- 状态栏输入法:这个小不点儿,就在屏幕顶上,不占地儿。
- 多设备部署:你开发的输入法,手机、平板都能用。
- 自定义编辑框:你想让你的应用里的输入框与众不同,IME Kit帮你实现。
- 文字输入、删除:用户输入文字或者删除文字,IME Kit都能搞定。
- 光标移动、文本选择:用户想在哪儿编辑就在哪儿编辑,IME Kit提供这些操作的支持。
- 系统应用管理:系统级别的输入法管理,比如显示/隐藏输入法软键盘,切换输入法等。
代码实战
下面是根据文件内容整理的代码实例,咱们一块儿看看。
KeyboardKeyData.ts
// 定义键盘按键的数据结构
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: '\\' }
];
KeyboardController.ts
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');
}
}
InputMethodService.ts
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();
}
}
Index.ets
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上开发出自己的输入法应用。如果有啥问题或者需要进一步的帮助,随时来聊!👍🏻
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
赞
收藏
回复
相关推荐