How to set focus on a view when a layout is created and displayed?

Viewed 173547

Currently, I have a layout which contains a Button, a TextView and an EditText. When the layout is displayed, the focus will be automatically put on the EditText, which will trigger the keyboard to show up on Android phone. It is not what I want. Is there any way that I can set the focus on TextView or on nothing when a layout is displayed?

17 Answers

Set focus: The framework will handled moving focus in response to user input. To force focus to a specific view, call requestFocus()

This works:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

you can add an edit text of size "0 dip" as the first control in ur xml, so, that will get the focus on render.(make sure its focusable and all...)

You can add

       android:importantForAccessibility="yes"
       android:focusable="true"
       android:focusableInTouchMode="true"

to your Layout to force Talkback/accessibility to go there first.

You really only need the first line, however, the others reinforce to the OS what you want focused.

You can use the following Kotlin extension

fun View.focusAndShowKeyboard() {
  /**
   * This is to be called when the window already has focus.
   */
  fun View.showTheKeyboardNow() {
    if (isFocused) {
      post {
        // We still post the call, just in case we are being notified of the windows focus
        // but InputMethodManager didn't get properly setup yet.
        val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
      }
    }
  }

  requestFocus()

  if (hasWindowFocus()) {
    // No need to wait for the window to get focus.
    showTheKeyboardNow()
  } else {
    // We need to wait until the window gets focus.
    viewTreeObserver.addOnWindowFocusChangeListener(
      object : ViewTreeObserver.OnWindowFocusChangeListener {
        override fun onWindowFocusChanged(hasFocus: Boolean) {
          // This notification will arrive just before the InputMethodManager gets set up.
          if (hasFocus) {
            this@focusAndShowKeyboard.showTheKeyboardNow()
            // It’s very important to remove this listener once we are done.
            viewTreeObserver.removeOnWindowFocusChangeListener(this)
          }
        }
      }
    )
  }
}

And just call your view.focusAndShowKeyboard() in override fun onViewCreated(..) or override fun OnCreate(..)

PS: For hiding Views use the following extension

fun View.hideKeyboard() {
  val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  imm.hideSoftInputFromWindow(windowToken, 0)
}

Make sure the views are focusable before that using the following android XML attributes, u can also do it programmatically

android:focusableInTouchMode="true"
android:focusable="true"
Related