在 Android 键盘中每两个键输出一个字符
Output one character per two keys in Android Keyboard
我正在为 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,在 StartInput 上清除它,并在有新输入时更新它。
- 减少字符串的使用。我已经使用自定义 class 替换了字符串并重组了您的转换映射。
- 使用撰写文本更好地提示用户您正在做什么。
这里是修改后的代码
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);
}
跳过尝试。
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);
}
我正在为 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,在 StartInput 上清除它,并在有新输入时更新它。
- 减少字符串的使用。我已经使用自定义 class 替换了字符串并重组了您的转换映射。
- 使用撰写文本更好地提示用户您正在做什么。
这里是修改后的代码
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);
}
跳过尝试。
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);
}