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

17

96

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?

Eelpout answered 27/1, 2010 at 22:9 Comment(0)
E
111

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

Eldridgeeldritch answered 27/1, 2010 at 22:11 Comment(0)
J
17

This works:

getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
Jam answered 9/12, 2010 at 18:52 Comment(2)
What does it do? It seems like it's modifying some state for the entire activity, and not just a view or fragment, so I'd be cautious about this, and not use it unless I understand all its implications.Cyclometer
Indeed I would not do this based on the original poster's request. This may solve the current issue, but using it has side-effects that could cause problems later. It's hacks like this that make their way into code bases that cause other hacks to be added later on to negate the original hack..the vicious cycle continues....and people wonder why code becomes unmaintainable. Yep, you guessed it....I work with others who do stuff like this and it makes my life very difficult.Inharmonic
M
8

You should add this:

android:focusableInTouchMode="true"
Marginal answered 11/3, 2011 at 10:38 Comment(0)
A
7

To set focus, delay the requestFocus() using a Handler.

private Handler mHandler= new Handler();

public class HelloAndroid extends Activity {
   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     LinearLayout mainVw = (LinearLayout) findViewById(R.id.main_layout);

     LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( 
           LinearLayout.LayoutParams.FILL_PARENT,
           LinearLayout.LayoutParams.WRAP_CONTENT);

     EditText edit = new EditText(this);
     edit.setLayoutParams(params);
     mainVw.addView(edit);

     TextView titleTv = new TextView(this);
     titleTv.setText("test");
     titleTv.setLayoutParams(params);
     mainVw.addView(titleTv);

     mHandler.post(
       new Runnable() 
       {
          public void run() 
          {
            titleTv.requestFocus();
          } 
       }
     );
   }
}
Annorah answered 17/12, 2011 at 17:51 Comment(0)
C
6

Set

 android:focusable="true"

in your <EditText/>

Cashandcarry answered 20/9, 2010 at 13:9 Comment(0)
C
5

You can try just hidding the keyboard. Something like this:

InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
Contactor answered 18/1, 2012 at 7:50 Comment(0)
M
4

Set these lines to OnResume as well and make sure if focusableInTouch is set to true while you initialize your controls

<controlName>.requestFocus();

<controlName>.requestFocusFromTouch();
Movement answered 30/5, 2011 at 10:3 Comment(1)
Thanks for requestFocusFromTouch(). I added android:focusableInTouchMode="true" and android:focusable="true" in a container (a problem appeared in API 24).Crosshead
F
3

Try

comp.requestFocusInWindow();
Furculum answered 22/6, 2010 at 8:43 Comment(0)
E
3

to change the focus make the textView in xml focusable

<TextView
            **android:focusable="true"**
            android:id="@+id/tv_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

and in java in on create

textView.requestFocus();

or simply hide the keyboard

public void hideKeyBoard(Activity act) {
    act.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
    InputMethodManager imm = (InputMethodManager) act.getSystemService(Context.INPUT_METHOD_SERVICE);
}
Elsworth answered 27/3, 2018 at 14:58 Comment(1)
android:focusable="true" and textView.requestFocus(); worked for me. Thanks!Diadiabase
H
2

The last suggestion is the correct solution. Just to repeat, first set android:focusable="true" in the layout xml file, then requestFocus() on the view in your code.

Hertzog answered 27/9, 2010 at 20:50 Comment(0)
S
2

None of the answers above works for me. The only (let's say) solution has been to change the first TextView in a disabled EditText that receives focus and then add

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

in the onCreate callback to prevent keyboard to be shown. Now my first EditText looks like a TextView but can get the initial focus, finally.

Sizzle answered 16/2, 2012 at 17:9 Comment(0)
K
1

i think a text view is not focusable. Try to set the focus on a button for example, or to set the property focusable to true.

Kremenchug answered 7/10, 2010 at 7:55 Comment(0)
O
1

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...)

Onyx answered 28/1, 2011 at 5:3 Comment(0)
C
1

You can start by adding android:windowSoftInputMode to your activity in AndroidManifest.xml file.

<activity android:name="YourActivity"
          android:windowSoftInputMode="stateHidden" />

This will make the keyboard to not show, but EditText is still got focus. To solve that, you can set android:focusableInTouchmode and android:focusable to true on your root view.

<LinearLayout android:orientation="vertical"
              android:focusable="true"
              android:focusableInTouchMode="true"
              ...
              >
    <EditText
         ...
       />
    <TextView
         ...
       />
    <Button
         ...
       />
</LinearLayout>

The code above will make sure that RelativeLayout is getting focus instead of EditText

China answered 24/2, 2017 at 14:34 Comment(0)
B
1

Focus is for selecting UI components when you are using something besides touch (ie, a d-pad, a keyboard, etc.). Any view can receive focus, though some are not focusable by default. (You can make a view focusable with setFocusable(true) and force it to be focused with requestFocus().)

However, it is important to note that when you are in touch mode, focus is disabled. So if you are using your fingers, changing the focus programmatically doesn't do anything. The exception to this is for views that receive input from an input editor. An EditText is such an example. For this special situation setFocusableInTouchMode(true) is used to let the soft keyboard know where to send input. An EditText has this setting by default. The soft keyboard will automatically pop up.

If you don't want the soft keyboard popping up automatically then you can temporarily suppress it as @abeljus noted:

InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

When a user clicks on the EditText, it should still show the keyboard, though.

Further reading:

Barratry answered 12/6, 2017 at 6:33 Comment(1)
Is this answer wrong? No comment was left with the downvote.Barratry
C
1

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.

Czardas answered 29/4, 2021 at 20:15 Comment(0)
U
0

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) {
            [email protected]()
            // 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"
Undertrump answered 9/2, 2022 at 15:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.