0

I'm playing with WindowInsets API to opening/hiding keyboard, but it seems to doesnt work with Compat version (target API 29) or something.

fun View.hideKeyboard() {
    ViewCompat.getWindowInsetsController(this)?.hide(WindowInsetsCompat.Type.ime())
}

fun View.showKeyboard() {
    ViewCompat.getWindowInsetsController(this)?.show(WindowInsetsCompat.Type.ime())
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<EditText>(R.id.text).showKeyboard()
    }
}

Layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
implementation 'androidx.core:core-ktx:1.6.0-alpha01'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'

Any suggestions?

khoben
  • 108
  • 1
  • 8
  • Control over IME window was added natively in api 29 and (as far as I'm aware) there's no way to add compat behavior so that method does nothing. You'll need to fall back to old tricks like forcing focus of edit text. – Pawel Apr 13 '21 at 11:33
  • @Pawel thanks for your answer, it's strange that the old trick was not added inside a compatible method. As for other similar compatible methods there should be a wrapper for the new and old api. – khoben Apr 14 '21 at 01:38

1 Answers1

1

Referring to WindowInsetsControllerCompat source, here is view.hasWindowFocus() returns false as the window hasn't got focus yet. If set keyboard interaction to buttons then window has time to get focus and everything is OK.

Here are two ways:

  1. Waiting for focus changing to true with viewTreeObserver.addOnWindowFocusChangeListener:
    editText.viewTreeObserver.addOnWindowFocusChangeListener(
                object : ViewTreeObserver.OnWindowFocusChangeListener {
                    override fun onWindowFocusChanged(hasFocus: Boolean) {
                        if (hasFocus) {
                            editText.showKeyboard()
                            // show only once
                            editText.viewTreeObserver.removeOnWindowFocusChangeListener(this)
                        }
                    }
                })
    
  2. Make keyboard is visible when window receives focus:
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE)
    editText.showKeyboard()
    
khoben
  • 108
  • 1
  • 8