8

I have a list of EditTexts in an android layout. Each one is labeled with a TextView, so no hint is necessary in portrait mode, and a hint would even be redundant. However, in landscape mode, many people have keyboards configured to take full screen and hide the app until the keyboard is hidden and the input is injected into the selected view:

SwiftKey keyboard in landscape fullscreen extract ui mode

This may be fine if you have one EditText field for input, but if you have a list, nobody is memorizing the six TextView labels before going through the inputs.

How can I set a hint that only appears if the keyboard is in extract ui mode - be it in landscape or portrait orientation?

Menasheh
  • 3,560
  • 3
  • 33
  • 48
  • you can keep different layout files for the landscape and portrait modes in the `layout-land`, `layout-port` folders (in the `res/` directory) – Ashish Ranjan Jul 19 '16 at 20:48
  • @AshishRanjan But while the keyboard is not shown and is not in extracted ui mode, I don't need the android:hint at all. – Menasheh Jul 19 '16 at 20:50
  • you can then override the `onFocusChanged()` method for the edittext and check the screen orientation there, if landscape add a hint to it. – Ashish Ranjan Jul 19 '16 at 20:51
  • or simply you can set `android:imeOptions="flagNoExtractUi"` for your edittext to avoid the extracted ui mode. – Ashish Ranjan Jul 19 '16 at 20:53
  • 1
    I did actually try the `android:imeOptions="flagNoExtractUi"` but there still wasn't enough space for it to be ideal. As for the onFocusChanged(), I don't want the hint visible when the keyboard is hidden or if the keyboard is not in extract ui mode. – Menasheh Jul 19 '16 at 21:07

1 Answers1

1

I managed to solve this using InputConnectionWrapper, which has an explicit callback for entering fullscreen mode.

/**
 * [InputConnection] wrapper which applies hint text to 
 * the IME when entering fullscreen mode.
 */
class FullscreenHintInputConnection(
    delegate: InputConnection,
    private val editText: EditText,
    private val hintText: CharSequence
) : InputConnectionWrapper(delegate, false) {

    override fun reportFullscreenMode(enabled: Boolean): Boolean {
        if (enabled) {
            editText.hint = hintText
        } else {
            editText.hint = null
        }
        return super.reportFullscreenMode(enabled)
    }
}

In an EditText subclass:

override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
    val connection = super.onCreateInputConnection(outAttrs)
    return FullscreenHintInputConnection(connection, this, "Lorem ipsum")
}

While this solution works, it's worth noting that AppCompat manages to do this a little more elegantly. The library modifies the EditorInfo argument passed into onCreateInputConnection, avoiding the InputConnectionWrapper subclass entirely.

AppCompatEditText.java

@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
    return AppCompatHintHelper.onCreateInputConnection(
            super.onCreateInputConnection(outAttrs),
            outAttrs, 
            this
    );
}

AppCompatHintHelper.java

class AppCompatHintHelper {
    static InputConnection onCreateInputConnection(InputConnection ic, EditorInfo outAttrs,
            View view) {
        if (ic != null && outAttrs.hintText == null) {
            ViewParent parent = view.getParent();
            while (parent instanceof View) {
                if (parent instanceof WithHint) {
                    outAttrs.hintText = ((WithHint) parent).getHint();
                    break;
                }
                parent = parent.getParent();
            }
        }
        return ic;
    }
}

This is used to apply a hint supplied from a TextInputLayout to the underlying TextInputEditText. Some of these APIs are restricted to the library and therefore you would need to copy them into your own project. But unfortunately, this technique isn't working for me so far, the hint remains blank.

Damien Diehl
  • 383
  • 4
  • 13
  • AppCompatEditText/AppCompatHintHelper worked perfectly for me. The only difference is I have a custom parent object to that generates hint text – Jerry Sha Oct 31 '18 at 12:02