Search code examples
androidandroid-layoutandroid-input-method

How to use "android:inputMethod" attribute?


I need to use custom input method for specific edit texts inside my app.

Input method successfully works with all apps (when I select it from the system menus). So all OK with the method.

But when I tries to force its use explicitly:

<EditText
    android:id="@+id/edit"
    android:inputMethod="tx.android.softkeyboard.TXSoftKeyboard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

it triggers ClassNotFoundException

Caused by: java.lang.ClassNotFoundException: tx.android.softkeyboard.TXSoftKeyboard
        at java.lang.Class.classForName(Native Method)
        at java.lang.Class.forName(Class.java:400)
        at java.lang.Class.forName(Class.java:326)
        at android.widget.TextView.<init>(TextView.java:1233)
        at android.widget.EditText.<init>(EditText.java:64) 

Class tx.android.softkeyboard.TXSoftKeyboard exists of course.

In another topic user m0skit0 reported similar behaviour but no solutions..


Solution

  • I've checked in AOSP and in TextView you can clearly see that the value of the attribute is not modified (it's easy to follow, in line 1034 the attribute is fetched and later is used in the following piece of code):

        if (inputMethod != null) {
            Class<?> c;
            try {
                c = Class.forName(inputMethod.toString());
            } catch (ClassNotFoundException ex) {
                throw new RuntimeException(ex);
            }
            try {
                createEditorIfNeeded();
                mEditor.mKeyListener = (KeyListener) c.newInstance();
            } catch (InstantiationException ex) {
                throw new RuntimeException(ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException(ex);
            }
            try {
                mEditor.mInputType = inputType != EditorInfo.TYPE_NULL
                        ? inputType
                        : mEditor.mKeyListener.getInputType();
            } catch (IncompatibleClassChangeError e) {
                mEditor.mInputType = EditorInfo.TYPE_CLASS_TEXT;
            }
        }
    

    So, the closest we can get to work around this is calling TextView#setKeyListener() (that basically is what this piece of code is doing, notice the cast after creating the instance of the class once it is loaded mEditor.mKeyListener = (KeyListener) c.newInstance();). That being said, from my limited understanding of this topic, KeyListener is not what you're looking for.