2015-09-01 6 views
10

Ich entwerfe eine benutzerdefinierte Tastatur für Amharisch Sprache in Android, aber das Folgende ist auf viele andere nicht-Englisch Sprachen anwendbar.Ausgabe eines Zeichens pro zwei Tasten in Android-Tastatur

Zwei oder mehrere Tastenkombinationen werden in ein Zeichen übersetzt. Wenn der Benutzer also 'S' eintippt, gibt die Tastatur 'ሰ' aus ... und wenn sie dem Buchstaben 'A' folgen, wird 'ሰ' durch 'ሳ' ersetzt.

Es gelang mir, eine Lösung zu finden, wie unten, indem ich das Zeichen vor dem Cursor betrachtete und es mit einer Map abtastete. Ich habe mich jedoch gefragt, ob es eine einfachere und sauberere Lösung gibt.

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); 
} 

Antwort

3

Hier sind einige Änderungen, die ich vorschlagen würde, ist es effizienter

  1. Verwenden Sie Ihre eigene Variable, um den Bearbeitungsstatus zu verfolgen. In dem folgenden Code habe ich mComposing verwendet, es bei StartInput gelöscht und es aktualisiert, wenn eine neue Eingabe erfolgt.
  2. Reduzieren Sie die Verwendung von String. Ich habe Strings mit einer benutzerdefinierten Klasse ersetzt und Ihre Conversion-Map neu strukturiert.
  3. Verwenden Sie Texterstellung, um dem Benutzer einen besseren Hinweis darauf zu geben, was Sie tun. Hier

ist der modifizierte Code

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); 
} 
+0

Entschuldigung war für einige Zeit offline. Wie vergebe ich dir eine volle Prämie von 50 Punkten? –

+0

Ich denke, du kannst nicht, aber es ist in Ordnung. :) –

1

initialisieren en_to_am in statischen Code

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); 
} 

den Versuch überspringen.

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); 
} 
Verwandte Themen