13

Ich renne in ein Problem, das ich nicht herausfinden kann. Ich schrieb eine einfache benutzerdefinierte IME-Tastatur basierend auf this Beispiel.Custom Keyboard: Umgang EingabeType ändern

Es hat im Grunde zwei benutzerdefinierte Tastaturen, eine für Buchstaben und eine für Zahlen. Sie verwenden unterschiedliche Layouts.

Wenn ich jedoch zwei EditText Steuerelemente eins für Text und eins für Zahlen hinzufüge, wird die Tastatur nicht zu dem Typ aktualisiert, zu dem sie gehört. Was ich meine ist, dass, wenn ich zuerst die EditText mit inputType="text" auswähle, das QWERTY Tastaturlayout auftaucht. Aber dann, wenn ich die zweite EditText mit inputType="number" wähle, erscheint die QWERTY-Tastatur wieder. Es soll jedoch ein anderes Layout für Zahlen laden, das mit dem Code verdrahtet ist.

Mit anderen Worten, hier ist die Testaktivität Layout:

enter image description here

Nun, wenn ich das Feld "Text" wählen, kommt die QWERTZ-Tastatur wie unten nach oben:

enter image description here

Wenn ich jedoch das Feld "Number" wähle, wird immer noch die QWERTY-Tastatur angezeigt, die falsch ist.

enter image description here

Das würde erwartete Verhalten dieser Tastatur bis zu zeigen.

enter image description here

Hier ist der Code für die CustomIME und ich versuchte postInvalidate() auf die Ansicht, Vorbelastung alle Layouts während onInitializeInterface() zu verwenden, aber nichts funktionierte. Er schaltet nie richtig auf das Layout der Nummer

public class CustomIME extends InputMethodService 
     implements KeyboardView.OnKeyboardActionListener { 

    public static final String CUSTOM_IME = "CUSTOM_IME"; 
    private KeyboardView mKeyboardView; 
    private Keyboard mKeyboardCurrent; 
    private KeyboardType mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS; 
    private boolean mCAPs = false; 


    enum KeyboardType { 
     QWERTY_LETTERS, 
     NUMBERS 
    } 

    @Override 
    public View onCreateInputView() { 
     loadCurrentKeyboard(); 
     mKeyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.custom_ime_keyboard, null); 
     mKeyboardView.setBackgroundResource(R.drawable.btn_gradient); 
     mKeyboardView.setOnKeyboardActionListener(this); 

     if (mKeyboardCurrent != null) { 
      mKeyboardView.setKeyboard(mKeyboardCurrent); 
     } 

     return mKeyboardView; 
    } 

    @Override 
    public void onInitializeInterface() { 
     // tried loading everything here but did not make a difference 
    } 

    private void loadCurrentKeyboard() { 
     if (mKeyboardTypeCurrent == KeyboardType.QWERTY_LETTERS) { 
      mKeyboardCurrent = new Keyboard(getApplicationContext(), R.xml.custom_ime_qwerty); 
     } else if (mKeyboardTypeCurrent == KeyboardType.NUMBERS) { 
      mKeyboardCurrent = new Keyboard(getApplicationContext(), R.xml.custom_ime_number); 
     } else { 
      Log.e(CUSTOM_IME, "Invalid keyboard type"); 
     } 
    } 

    @Override 
    public void onStartInput(EditorInfo attribute, boolean restarting) { 
     super.onStartInput(attribute, restarting); 
     switch (attribute.inputType & InputType.TYPE_MASK_CLASS) { 
      case InputType.TYPE_CLASS_NUMBER: 
       boolean signed = (attribute.inputType & InputType.TYPE_NUMBER_FLAG_SIGNED) != 0; 
       boolean decimal = (attribute.inputType & InputType.TYPE_NUMBER_FLAG_DECIMAL) != 0; 

       // set default 
       mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS; 
       if (!signed && !decimal) { 
        mKeyboardTypeCurrent = KeyboardType.NUMBERS; 
       } 
       break; 
      case InputType.TYPE_CLASS_TEXT: 
      default: 
       mKeyboardTypeCurrent = KeyboardType.QWERTY_LETTERS; 
     } 

     // This did not make a difference 
     if (mKeyboardView != null) { 
      mKeyboardView.postInvalidate(); 
     } 
    } 

    @Override 
    public void onKey(int primaryCode, int[] keyCodes) { 
     InputConnection inputConnection = getCurrentInputConnection(); 
     switch (primaryCode) { 
      default: 
       char asciiCode = (char) primaryCode; 
       if (Character.isLetter(asciiCode) && mCAPs) { 
        asciiCode = Character.toUpperCase(asciiCode); 
       } 
       inputConnection.commitText(String.valueOf(asciiCode), 1); 
     } 
    } 
} 

und die Layouts:

custom_ime_keyboard.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<android.inputmethodservice.KeyboardView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/custom_ime_keyboard_id1" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:keyPreviewLayout="@layout/custom_ime_preview" /> 

activity_main.xml

<LinearLayout 
    android:id="@+id/layout1" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentTop="true" 
    android:layout_centerHorizontal="true" 
    android:layout_margin="10dp" 
    android:orientation="horizontal"> 

    <EditText 
     android:id="@+id/edit1" 
     android:layout_width="100dp" 
     android:layout_height="60dp" 
     android:inputType="text" 
     android:hint="Text" 
     android:padding="10dp" 
     android:textSize="12sp" /> 

    <EditText 
     android:id="@+id/edit2" 
     android:layout_width="100dp" 
     android:layout_height="60dp" 
     android:hint="Number" 
     android:inputType="number" 
     android:padding="10dp" 
     android:textSize="12sp" /> 
</LinearLayout> 

Schließlich werden die Tastaturlayouts (custom_ime_qwerty.xml und custom_ime_number.xml).

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" 
    android:keyHeight="64dp" 
    android:keyWidth="9%p"> 
    <!--1st row--> 
    <Row android:rowEdgeFlags="top"> 
     <Key 
      android:codes="113" 
      android:keyEdgeFlags="left" 
      android:keyLabel="q" /> 
     <Key 
      android:codes="119" 
      android:keyLabel="w" /> 
     <Key 
      android:codes="101" 
      android:keyLabel="e" /> 
     <Key 
      android:codes="114" 
      android:keyLabel="r" /> 
     etc... 


<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" 
    android:keyHeight="64dp" 
    android:keyWidth="20%p" 
    android:label="number" 
    android:verticalGap="0px"> 
    <!--1st row--> 
    <Row android:rowEdgeFlags="top"> 
     <Key 
      android:codes="49" 
      android:keyEdgeFlags="left" 
      android:keyLabel="1" /> 
     <Key 
      android:codes="50" 
      android:keyLabel="2" /> 
     <Key 
      android:codes="51" 
      android:keyLabel="3" /> 
+2

Ich glaube, dass Azizbekian korrekt ist. Sie müssen Ihren Code ändern, um 'onStartInputView()' hinzuzufügen. Es wird ungefähr so ​​aussehen. @Override öffentliche void onStartInputView (EditorInfo Info, boolean Neustart) { \t super.onStartInputView (Attribut, Neustart); \t loadCurrentKeyboard(); kv.setKeyboard (mKeyboardCurrent); } – Cheticamp

+0

Hier ist ein [gist] (https://gist.github.com/Cheticamp/597d6442218af34a3bfae773c286ef4e) mit Arbeitscode für einfache numerische und Text-Tastaturen. – Cheticamp

Antwort

9

Ich denke, onStartInputView() ist der Rückruf Sie erhalten müssen:

aufgerufen, wenn der Eingang Ansicht wird gezeigt und Eingang an einem neuen Editor gestartet. Dies wird immer nach onStartInput (EditorInfo, boolean) aufgerufen werden, so dass Sie Ihre allgemeine Einrichtung dort tun können und nur Ansicht-spezifische Setup hier. Sie haben garantiert, dass onCreateInputView() einige Zeit aufgerufen wurde, bevor diese Funktion aufgerufen wird.

So erhalten Sie wissen, welche Art genaue Eingabe in onStartInput() zu zeigen, aber der eigentlichen Ort, um diesen neuen Tastaturtyp Schalte ausführen soll onStartInputView() sein.

Sehen Sie, wie die Beispiel SoftKeyboard Anwendung diese Funktionalität behandelt.

 


@Override public void onStartInput(EditorInfo attribute, boolean restarting) { 
    super.onStartInput(attribute, restarting); 

    ... 

    // We are now going to initialize our state based on the type of 
    // text being edited. 
    switch (attribute.inputType & InputType.TYPE_MASK_CLASS) { 
     case InputType.TYPE_CLASS_NUMBER: 
     case InputType.TYPE_CLASS_DATETIME: 
      mCurKeyboard = mSymbolsKeyboard; 
      break; 

     case InputType.TYPE_CLASS_PHONE: 
      mCurKeyboard = mSymbolsKeyboard; 
      break; 

     case InputType.TYPE_CLASS_TEXT: 
      mCurKeyboard = mQwertyKeyboard; 
      ... 
      break; 

     default: 
      // For all unknown input types, default to the alphabetic 
      // keyboard with no special features. 
      mCurKeyboard = mQwertyKeyboard; 
    } 

} 

@Override public void onStartInputView(EditorInfo attribute, boolean restarting) { 
    super.onStartInputView(attribute, restarting); 
    // Apply the selected keyboard to the input view. 
    setLatinKeyboard(mCurKeyboard); 
    ... 
} 

private void setLatinKeyboard(LatinKeyboard nextKeyboard) { 
    final boolean shouldSupportLanguageSwitchKey = 
      mInputMethodManager.shouldOfferSwitchingToNextInputMethod(getToken()); 
    nextKeyboard.setLanguageSwitchKeyVisibility(shouldSupportLanguageSwitchKey); 
    mInputView.setKeyboard(nextKeyboard); 
} 

 
+0

Danke @azizbekian, das war es. Gern gebe ich dir 50 extra zu deinem Eimer. – gmmo