2

I know this question has been asked in many different ways before, but even though I have looked at many other related questions about EditText focus, I have not found my solution.

Here is what I want to achieve:

  • When the user is done Editing an EditText I want it to loose focus.

  • When the user hits outside the EditText I want such EditText to lose focus.

  • Whenever the soft-keyboard hides or is hidden I want EditText to lose focus.

  • Whenever the User hits ENTER or BACK ARROW in the soft-keyboard, the EditText focus should be cleared

This is what I currently have:

I have two EditText in an activity, which I will call EditText_1 and EditText_2 for simplicity so that we know which EditText I am talking about.

  1. When the user starts the activity, the EditText_1 would have no focus, a blinking cursor and the soft-keyboard would be hidden. I have already fixed that problem using;

    android:focusableInTouchMode="true"

    and

    android:focusable="true"

  2. After the previous fix in part1, when I start the activity and click on any EditText, it will gain focus, however, when I am done editing such clicked EditText and the soft-keyboard hides, the EditText will not lose focus and the cursor will still be blinking.

    Another example happens when I am editing an EditText and click any other button outside the editText, it will not force EditText to lose focus or hide the keyboard.

The current solution I have is

public void onFocusChange(View v, boolean hasFocus){...}

so that, it will call some method such as force the EditText to lose focus:

EditText.clearFocus();

and do not show that annoying blinking cursor once I know EditText loses its focus:

EditText.setCursorVisible(false);

However, because hitting Done or outside EditText do not force it to lose focus, onFocusChange will not be called all the times(as in the examples provided).

Some of the solutions I cannot accept are:

Set the cursor visibility to false in the XML activity file and never and anywhere change it back to true.

setCursorVisible(false);

I want the cursor to be seen when needed and to be hidden when it is not needed.

Have a button that needs to be clicked by the user so that inside such button all methods needed will be called. I mean, it is not user-friendly at all. Users do not want to be forced to click a button just to hide all focus, blinking cursors...

Here comes the part many of you will tell me, every single of these issues have been solved in different questions. HOWEVER, I have not been able to implement multiple solutions which will do all points previously stated.

ArtiomLK
  • 2,120
  • 20
  • 24

2 Answers2

1

To make editText lose focus when you press outside of the keyboard you can try to setOnTouchListener to the view that is visible when the keyboard is shown. For example, it might be the parent layout, listView, recyclerView or any other significant in size view. In order to do that, just add code below inside of your onCreate method in activity:

findViewById(R.id.loginLayout).setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        usernameEditText.clearFocus();
        passwordEditText.clearFocus();
        return false;
    }
});

To make editText lose focus and/or hide keyboard when pressing some button on keyboard you can use the following code. There is an example of listener for Enter key. You may find all the other keys on official documentation.

yourEditText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER) {
            if (event.getAction() == KeyEvent.ACTION_UP) {
                yourEditText.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            }
        }
        return false;
    }
});
Marat
  • 6,142
  • 6
  • 39
  • 67
  • Thanks, #Marat. The first part of the solution worked perfectly. Now, I would like to implement such function whenever the user clicks on anything else besides the parent layout. For instance, Buttons, CheckBoxes, Spinners, etc. The only way I see to do it, is about calling those methods again in all OnClickListeners. However, is there a way I can do it in just one function? Any suggestion? The second part of the solution I had to add android:imeOptions="actionNext" to EditText_1 for it to work. – ArtiomLK Oct 30 '16 at 06:38
  • @ArtiomLK I'm not 100% sure that there is one function that could trigger touch events. Maybe you could look at https://developer.android.com/training/graphics/opengl/touch.html and http://stackoverflow.com/a/17316038/6272369 . However, I think that you implement some kind of methods to your Buttons, Checkboxes and etc. Then you could enter portion of code that is inside of the first part of my answer to your methods of Buttons and other views and achieve focus lose. – Marat Oct 30 '16 at 07:55
  • Thanks for the help. If I create a function and add part of the code you provided in it, then I would have to call such function in every single Button, CheckBox, Spinner... I have. I do not have many of those so it should not be a problem, however I thought there might be a better way. Anyways, thanks a lot, your solution helped me get the main issues out of the way, now I just have to work with the code you provided me ))) – ArtiomLK Oct 30 '16 at 08:01
  • @ArtiomLK Glad to hear that. About the second option, `ime` attribute is used to change the icon on the bottom right corner button. You can choose from Enter, Search, Send, etc. However, it will also work without it. Happy coding) – Marat Oct 30 '16 at 09:55
  • the second part of the solution only works for Hard Keys, [View.OnKeyListener](https://developer.android.com/reference/android/view/View.OnKeyListener.html). _This is only useful for hardware keyboards; a software input method has no obligation to trigger this listener._ – ArtiomLK Jan 01 '17 at 20:51
  • @ArtiomLK so `onKeyListener` didn't work in your case? Strangely, it works in all of my projects and testing on real device is successful. – Marat Jan 02 '17 at 18:27
  • I am testing on a Nexus 5X and it did not call the `onKeyListener` however it did call the `onEditorActionListener`. The first part of the solution works in my case though. – ArtiomLK Jan 05 '17 at 00:16
1

This Solution works For SOFTKEYS, some code is from here

The final solution to hide keyboard and clear focus from the EditText would be;

yourEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                name.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                Log.d(TAG, "actionID: " + actionId +"  KeyEvent: " + event);
            }
            return false;
        }
    });
Community
  • 1
  • 1
ArtiomLK
  • 2,120
  • 20
  • 24