Search code examples
androidandroid-softkeyboardimesubtype

How to load a different keyboard layout for subtype in android?


I'm using the android sample keyboard. it includes En (US) and En (GB) subtypes. On selecting either of the subtypes it only changes the flag on the spacebar.

Say I want to change the layout based on whichever subtype is selected but I am unable to do so.

So far, I have created another xml file for English (GB) and I call it qwerty_gb.xml (for the purpose of testing, I have swapped the Return and Del keys)

Then declared private

LatinKeyboard mQwertyKeyboardGB;

and initialized it along with the default keyboards in the onInitializeInterface overrid method of Softkeyboard.java

like so:

mQwertyKeyboardGB = new LatinKeyboard(this, R.xml.qwerty_gb);

I don't know what am I missing here.


Solution

  • Edit the SoftKeyboard.java file with following modifications in order to have specific layout for each subtype.

    1- Reference your layouts first.

    mQwertyKeyboard = new LatinKeyboard(this, R.xml.qwerty);
    mPersianKeyboard = new LatinKeyboard(this, R.xml.persian);
    

    2- In the OnCreateInputView add the following to apply the right layout.

    InputMethodSubtype subtype = mInputMethodManager.getCurrentInputMethodSubtype();
    switch(subtype.getLocale()) {
        case "fa_IR":
            setLatinKeyboard(mPersianKeyboard);
            break;
        case "en_US":
            setLatinKeyboard(mQwertyKeyboard);
            break;
    }
    

    The above code applies mPersianKeyboard if the locale is fa_IR. The locale fa_IR is set in the method.xml.

    <subtype
        android:label="@string/label_subtype_generic"
        android:icon="@drawable/icon_en_us"
        android:imeSubtypeLocale="en_US"
        android:imeSubtypeMode="keyboard" />
    <subtype
        android:label="@string/label_subtype_generic"
        android:icon="@drawable/icon_en_gb"
        android:imeSubtypeLocale="fa_IR"
        android:imeSubtypeMode="keyboard" />
    

    3- And finally modify `onCurrentInputMethodSubtypeChanged method to the following:

    @Override
    public void onCurrentInputMethodSubtypeChanged(InputMethodSubtype subtype) {
        mInputView.setSubtypeOnSpaceKey(subtype);
        switch(subtype.getLocale()) {
            case "fa_IR":
                setLatinKeyboard(mSymbolsKeyboard);
                break;
            case "en_US":
                setLatinKeyboard(mQwertyKeyboard);
                break;
        };
    }
    

    Note: The getLocale() method was deprecated in API level 24. Use getLanguageTag() instead. The better is to check the version and use the right method for the right version.