
回复
在鸿蒙输入法中实现多语言/模式切换,核心在于子类型(Subtype)的灵活配置与动态加载。本文用最简流程带你掌握核心逻辑~
{
"subtypes": [
{
"id": "en_us", // 唯一标识
"label": "English", // 显示名称
"locale": "en-US", // 语言区域
"mode": "qwerty", // 键盘模式
"icon": "$media:en_icon" // 切换图标
},
{
"id": "zh_cn",
"label": "中文",
"locale": "zh-CN",
"mode": "pinyin",
"icon": "$media:cn_icon"
}
]
}
{
"extensionAbilities": [
{
"type": "inputMethod",
"metadata": [
{
"name": "ohos.extension.input_method",
"resource": "$profile:input_method_config" // 关联配置文件
}
]
}
]
}
inputMethodAbility.on('setSubtype', (subtype) => {
switch (subtype.id) {
case 'en_us':
this.loadEnglishKeyboard(); // 加载英文布局
break;
case 'zh_cn':
this.loadChineseKeyboard(); // 加载中文布局
break;
}
});
// 英文键盘布局
private loadEnglishKeyboard() {
this.panel.setUiContent(() => {
Grid() {
ForEach(englishKeys, (key) => {
Button(key.char)
.width(40)
.height(40)
.onClick(() => this.insertText(key.char));
});
}
});
}
// 中文键盘布局
private loadChineseKeyboard() {
this.panel.setUiContent(() => {
Grid() {
ForEach(chineseKeys, (key) => {
Button(key.pinyin)
.width(50)
.height(50)
.onClick(() => this.searchPinyin(key.pinyin));
});
// 候选词栏
Row() {
ForEach(candidates, (word) => {
Text(word).onClick(() => this.commitText(word));
});
}
}
});
}
// 切换按钮点击事件
async switchSubtype(targetId: string) {
const subtypes = await inputMethod.getSetting().listCurrentInputMethodSubtype();
const targetSubtype = subtypes.find(s => s.id === targetId);
if (targetSubtype) {
await inputMethod.switchCurrentInputMethodSubtype(targetSubtype);
}
}
// 检测到英文输入时自动切换
private detectLanguage(text: string) {
const isEnglish = /^[a-zA-Z]+$/.test(text);
if (isEnglish && this.currentSubtype.id !== 'en_us') {
this.switchSubtype('en_us');
} else if (!isEnglish && this.currentSubtype.id !== 'zh_cn') {
this.switchSubtype('zh_cn');
}
}
// 在onCreate中预加载所有子类型布局
private preloadLayouts() {
this.loadEnglishKeyboard(); // 提前渲染英文布局
this.loadChineseKeyboard(); // 提前渲染中文布局
}
// 布局切换时添加渐变动画
panel.setUiContent(() => {
Column() {
// 当前布局
if (currentSubtype === 'en_us') EnglishKeyboard()
else ChineseKeyboard()
}.animate({ type: 'opacity', duration: 300 }); // 300ms渐变
});