我正在为Android中的阿姆哈拉语设计一个自定义键盘,但以下内容适用于许多其他非英语语言。
两个或多个键的组合可转换为一个字符。所以,如果用户输入'S',键盘将输出' '…如果后面跟字母"A",那么"就会被"代替。
我设法得到了一个解决方案,如下所示,通过在光标之前查看字符并根据Map检查它来工作。然而,我想知道是否有一个更简单、更干净的解决方案。
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
HashMap<String, Integer> en_to_am = new HashMap<String, Integer>();
CharSequence pChar = ic.getTextBeforeCursor(1, 0);
int outKey = 0;
//build a hashmap of 'existing character' + 'new key code' = 'output key code'
en_to_am.put("83", 4656);
en_to_am.put("ሰ65", 4659);
try {
//see if config exists in hashmap for 'existing character' + 'new key code'
if (en_to_am.get(pChar.toString() + primaryCode) != null) {
outKey = en_to_am.get(pChar.toString() + primaryCode);
ic.deleteSurroundingText(1, 0);
} else {
//else just translate latin to amharic (ASCII 83 = ሰ)
if (en_to_am.get("" + primaryCode) != null) {
outKey = en_to_am.get("" + primaryCode);
} else {
//if no translation exists, just output the latin code
outKey = primaryCode;
}
}
} catch (Exception e) {
outKey = primaryCode;
}
char code = (char) outKey;
ic.commitText(String.valueOf(code), 1);
}
我建议你做一些改变,让它更有效率
- 使用您自己的变量来跟踪编辑状态。在下面的代码中,我使用了mcompositing,在starttinput时清除它,并在新输入时更新它。
- 减少使用字符串。我已经使用自定义类替换了字符串,并重新构建了转换映射。
- 使用组合文本给用户更好的提示你正在做什么。
下面是修改后的代码
private StringBuilder mComposing = new StringBuilder();
private static HashMap<Integer, CodeInfo> mCodeMap = new HashMap<Integer, CodeInfo>();
private static class CodeInfo {
final Character mCode;
final Map<Character, Character> mCombinedCharMap;
CodeInfo(Character code, Map<Character, Character> combinedCharMap) {
mCode = code;
mCombinedCharMap = combinedCharMap;
}
}
static {
//reminder, do not input combinedCharMap as null
mCodeMap.put(83, new CodeInfo(Character.valueOf((char)4656), new HashMap<Character, Character>());
HashMap<Character, Character> combinedCharMap = new HashMap<Character, Character>();
combinedCharMap.put(Character.valueOf('ሰ'), Character.valueOf((char)4659))
mCodeMap.put(65, new CodeInfo(null, combinedCharMap);
}
@Override
public void onStartInput(EditorInfo attribute, boolean restarting) {
super.onStartInput(attribute, restarting);
mComposing.setLength(0);
//other codes you already have
}
public void onKey(int primaryCode, int[] keyCodes) {
InputConnection ic = getCurrentInputConnection();
CodeInfo codeInfo = mCodeMap.get(primaryCode);
Character output = null;
if (codeInfo != null) {
if (mComposing.length() > 0) {
Character combinedOutput = codeInfo.mCombinedCharMap.get(mComposing.charAt(0));
if (combinedOutput != null) {
//the length is mComposing is expected to be 1 here
mComposing.setCharAt(0, combinedOutput);
ic.finishComposingText();
ic.setComposingText(mComposing, 1);
return;
}
}
output = codeInfo.mCode;
}
if (mComposing.length() > 0) {
mComposing.setLength(0);
ic.finishComposingText();
}
mComposing.append(output==null?(char)primaryCode:(char)output);
ic.setComposingText(mComposing, 1);
}
在静态代码中初始化en_to_am
static private Map<String, Integer> en_to_am = new HashMap<String,Integer>;
static {
//build a hashmap of 'existing character' + 'new key code' = 'output key code'
en_to_am.put("83", 4656);
en_to_am.put("ሰ65", 4659);
}
跳过try。
public void onKey(int primaryCode) {
InputConnection ic = getCurrentInputConnection();
CharSequence pChar = ic.getTextBeforeCursor(1, 0);
Integer pairInt = en_to_am.get(pChar.toString() + primaryCode);
Integer singleInt = en_to_am.get(primaryCode.toString());
int outKey = primaryCode;
if (pairInt != null) {
try {
ic.deleteSurroundingText(1, 0);
outkey = pairInt;
}
}
else if (singleInt != null) {
outkey = singleInt;
}
ic.commitText((char) outkey).toString()), 1);
}