我正在
Android中为阿姆哈拉语言设计一个自定义键盘,但以下内容适用于许多其他非英语语言.
两个或更多个键的组合转换为一个字符.所以,如果用户键入’S’,键盘将输出’ሰ’…如果它们用字母’A’后跟,’ሰ’替换为’ሳ’.
我设法得到一个解决方案,如下所示,通过查看光标前的字符并对其进行检查.不过,我想知道是否有更简单和更干净的解决方案成为可能.
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); }
解决方法
这里有一些改变,我建议使它更有效率
>使用自己的变量跟踪编辑状态.在下面的代码中,我使用mComposing,将其清除为onStartInput,并在新的输入时进行更新.
>减少使用String.我已经使用自定义类替换了字符串,重组了转换映射.
>使用撰写文字给用户更好的提示你在做什么.
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); }