2015-09-01 24 views
10

Sto progettando una tastiera personalizzata per la lingua Amharic in Android, ma quanto segue è applicabile a molte altre lingue diverse dall'inglese.Uscita di un carattere per due tasti nella tastiera Android

Due o più combinazioni di tasti si traducono in un carattere. Quindi, se l'utente digita 'S', la tastiera emetterà 'ሰ' ... e se la seguono con la lettera 'A', la 'ሰ' viene sostituita con 'ሳ'.

Sono riuscito a ottenere una soluzione, come di seguito, lavorando osservando il carattere prima del cursore e controllandolo contro una mappa. Tuttavia, mi chiedevo se fosse possibile una soluzione più semplice e pulita.

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

risposta

3

Ecco alcuni cambiamenti vorrei suggerire di rendere più efficiente

  1. utilizzare il proprio variabile per tenere traccia dello stato di modifica. Nel codice qui sotto, ho usato mComposing, cancellarlo su StartInput e aggiornarlo quando viene effettuato un nuovo input.
  2. Ridurre l'uso di String. Ho sostituito String utilizzando una classe personalizzata e ristrutturato la tua mappa di conversione.
  3. Utilizzare il testo di composizione per fornire un suggerimento migliore all'utente su ciò che si sta facendo.

Ecco il codice modificato

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

Siamo spiacenti, è offline per qualche tempo. Come posso assegnarti una taglia piena di 50 punti? –

+0

Immagino che tu non possa, ma va bene. :) –

1

inizializzazione en_to_am in codice statico

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

Salta la prova.

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