25

In my activity, I have a editText field. When the user taps on it, the editText gains the focus and the keyboard appears. Now, when the user presses the hardware back button on the phone, the keyboard disappears but the cursor remains in the Edittext, i. e., it still has the focus. Is it possible to make the EditText lose focus when back button is pressed? I tried using the following code but it didn't work:

@Override
public void onBackPressed() {
    vibrator.vibrate(Constants.DEFAULT_VIBRATE_TIME);
    myEditText.clearFocus();
            super.onBackPressed();
}
Ankush
  • 791
  • 2
  • 9
  • 20
  • 1
    make sure myEditText is not first input element in your layout.if yes then first remove Focus from EditText and then make focus to any other element like TextView etc – ρяσѕρєя K Dec 20 '12 at 15:15
  • It was the first input element in my activity. I tried `title.requestFocus()` but it didn't work – Ankush Dec 20 '12 at 15:19
  • first make title focusable then call title.requestFocus() – ρяσѕρєя K Dec 20 '12 at 15:22
  • its still not loosing focus – Ankush Dec 20 '12 at 15:24
  • Here is what you can use to hide keyboard without requiring a press on the back button (I know you want more btu that's still something) : this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); – PeterGriffin Dec 20 '12 at 15:26
  • @PeterGriffin Yeah, I saw this on another question, but this does not achieve what I really want – Ankush Dec 20 '12 at 15:29

6 Answers6

24

Just extend EditText:

public class EditTextV2 extends EditText
{
    public EditTextV2( Context context )
    {
        super( context );
    }

    public EditTextV2( Context context, AttributeSet attribute_set )
    {
        super( context, attribute_set );
    }

    public EditTextV2( Context context, AttributeSet attribute_set, int def_style_attribute )
    {
        super( context, attribute_set, def_style_attribute );
    }

    @Override
    public boolean onKeyPreIme( int key_code, KeyEvent event )
    {
        if ( key_code == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP )
            this.clearFocus();

        return super.onKeyPreIme( key_code, event );
    }
}

And in the xml just use <yourPackage.EditTextV2> instead of <EditText>.

Note: You may need to add/remove constructors to this class depending on the min API you're supporting. I suggest just adding them all and removing the ones whose super() calls get underlined in red.

Kacy
  • 3,330
  • 4
  • 29
  • 57
  • If we are to use the constructor: `EditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)` minimum API requirement is 21 [EditText](https://developer.android.com/reference/android/widget/EditText.html) – ArtiomLK Dec 30 '16 at 13:38
  • 2
    Perfectly elegant solution. Useful when you need to override the back button behavior using fragments using `View.OnKeyListener`, and need to capture a back button click event while a focus-stealing EditText interrupts your implementation. Cheers! – mwieczorek Mar 13 '17 at 10:17
  • 1
    This is an amazing solution. THANKSSSSS!!!!! – Nitin Tej Dec 20 '21 at 14:02
3

You can make another of your Views focusable, for example an ImageView. Be sure to make it focusable in touch mode, using setFocusableInTouchMode(true) and on onResume() make that View to requestFocus().

Also you can create a dummy View with 0 dimensions and perform same steps described above.

I hope this helps.

raukodraug
  • 11,519
  • 4
  • 35
  • 37
3

For anyone using Kotlin and Material Design, you can use this:

class ClearFocusEditText: TextInputEditText {
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {
        if(keyCode == KeyEvent.KEYCODE_BACK) {
            clearFocus()
        }

        return super.onKeyPreIme(keyCode, event)
    }
}
Philip Borbon
  • 707
  • 1
  • 11
  • 21
0

Add view like the following higher than your EditText:

<LinearLayout
    android:layout_width="0px"
    android:layout_height="0px"
    android:focusable="true"
    android:focusableInTouchMode="true" />

Also to hide keyboard add this in onBackPressed():

((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(myEditText.getWindowToken(), 0);
Artyom Kiriliyk
  • 2,513
  • 1
  • 17
  • 21
0

I am providing kotlin equivalent code to Kacy answer with some edit

class CustomSearch @JvmOverloads constructor(context: Context, attrs: AttributeSet? = 
null, defStyle: Int = 0):AppCompatEditText(context, attrs, defStyle) {
override fun onKeyPreIme(keyCode: Int, event: KeyEvent?): Boolean {
if (keyCode == KeyEvent.KEYCODE_BACK){
    val imm:InputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    imm.hideSoftInputFromWindow(this.windowToken, 0)
    this.clearFocus()
    //this.findFocus()
}
return true
}

Note: I am returning true and this is solving my problem i.e removing focus from edit text and hiding soft input

AZIM MOHAMAD
  • 72
  • 11
-3

This may be a possible solution:

EditText et;
et.setOnKeyListener(new View.OnKeyListener() {

        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
            if(i == KeyEvent.KEYCODE_BACK) {
                et.clearFocus();
                return true;
            }
            else return false;
        }
    });
Tamorak
  • 11
  • 3