在Android键盘中每两个键输出一个字符

Sha*_*ika 10 java android locale non-latin android-softkeyboard

我正在Android中为Amharic语言设计自定义键盘,但以下内容适用于许多其他非英语语言.

两个或多个键组合转换为一个字符.因此,如果用户键入'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);
}
Run Code Online (Sandbox Code Playgroud)

Der*_*ung 3

我建议进行一些更改以提高效率

\n\n
    \n
  1. 使用您自己的变量来跟踪编辑状态。在下面的代码中,我使用了 mComposition,在 StartInput 上清除它,并在进行新输入时更新它。
  2. \n
  3. 减少 String 的使用。我已经使用自定义类替换了字符串,并重构了您的转换映射。
  4. \n
  5. 使用撰写文本可以更好地提示用户您正在做什么。
  6. \n
\n\n

这是修改后的代码

\n\n
private StringBuilder mComposing = new StringBuilder();\nprivate static HashMap<Integer, CodeInfo> mCodeMap = new HashMap<Integer, CodeInfo>();\n\nprivate static class CodeInfo {\n   final Character mCode;\n   final Map<Character, Character> mCombinedCharMap;\n\n   CodeInfo(Character code, Map<Character, Character> combinedCharMap) {\n       mCode = code;\n       mCombinedCharMap = combinedCharMap;\n   }\n}\n\nstatic {\n    //reminder, do not input combinedCharMap as null\n\n    mCodeMap.put(83, new CodeInfo(Character.valueOf((char)4656), new HashMap<Character, Character>());\n    HashMap<Character, Character> combinedCharMap = new HashMap<Character, Character>();\n    combinedCharMap.put(Character.valueOf('\xe1\x88\xb0'), Character.valueOf((char)4659))\n    mCodeMap.put(65, new CodeInfo(null, combinedCharMap);\n}\n\n@Override \npublic void onStartInput(EditorInfo attribute, boolean restarting) {\n    super.onStartInput(attribute, restarting);\n    mComposing.setLength(0);\n\n\n    //other codes you already have\n}       \n\npublic void onKey(int primaryCode, int[] keyCodes) {\n    InputConnection ic = getCurrentInputConnection();\n\n    CodeInfo codeInfo = mCodeMap.get(primaryCode);\n    Character output = null;\n    if (codeInfo != null) {\n        if (mComposing.length() > 0) {\n            Character combinedOutput = codeInfo.mCombinedCharMap.get(mComposing.charAt(0));\n            if (combinedOutput != null) {\n                //the length is mComposing is expected to be 1 here\n                mComposing.setCharAt(0, combinedOutput);\n                ic.finishComposingText();\n                ic.setComposingText(mComposing, 1);\n                return;\n            }\n        }\n        output = codeInfo.mCode;        \n    }\n    if (mComposing.length() > 0) {\n       mComposing.setLength(0);\n       ic.finishComposingText();\n    }\n    mComposing.append(output==null?(char)primaryCode:(char)output);\n    ic.setComposingText(mComposing, 1);\n}\n
Run Code Online (Sandbox Code Playgroud)\n