77

How do I know when my edit text is done being edited? Like when the user selects the next box, or presses the done button on the soft keyboard.

I want to know this so I can clamp the input. It looks like text watcher's afterTextChanged happens after each character is entered. I need to do some calculations with the input, so I would like to avoid doing the calculation after each character is entered.

thanks

Matt
  • 2,650
  • 4
  • 36
  • 46

5 Answers5

111

By using something like this

 meditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            switch (actionId){
                case EditorInfo.IME_ACTION_DONE:
                case EditorInfo.IME_ACTION_NEXT:
                case EditorInfo.IME_ACTION_PREVIOUS:
                    yourcalc();
                    return true;
            }
            return false;
        }
    });
Kostanos
  • 9,615
  • 4
  • 51
  • 65
Reno
  • 33,594
  • 11
  • 89
  • 102
  • OK, yours and Rich's responses seem to be what I need, thanks. Is there a way to unfocus the editText when the user hits done with this method? I've tried v.clearfocus, but that doesn't seem to do anything... If I could unfocus then it would just pass the action to the on focus change listener. – Matt Feb 24 '11 at 23:03
  • 1
    @Matt: I think the problem is, that the button is not grabbing focus? I implemented a routine, where the button would pruposely grab focus in on click (I think the method is called requestFocus). Because if the button grabs focus your Textfield would lose it and all would be well. – AgentKnopf Apr 30 '12 at 21:09
  • if after editing text in edittext user press back instead of done button in softinput . then what happen? in that case yourcalc() method called or not? – Brijesh Patel Oct 05 '13 at 11:23
  • Will this also catch the event when manually switching focus on other view? – mr5 Jul 27 '16 at 09:09
  • 2
    you can also handle actions like: `EditorInfo.IME_ACTION_NEXT` and `IME_ACTION_PREVIOUS`. I just edited the answer by adding those to the code – Kostanos Apr 01 '19 at 19:49
43

EditText inherits setOnFocusChangeListener which takes an implementation of OnFocusChangeListener.

Implement onFocusChange and there's a boolean parameter for hasFocus. When this is false, you've lost focus to another control.

EDIT

To handle both cases - edit text losing focus OR user clicks "done" button - create a single method that gets called from both listeners.

    private void calculate() { ... }

    btnDone.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            calculate();
        }
    });

    txtEdit.setOnFocusChangeListener(new OnFocusChangeListener() {          

        public void onFocusChange(View v, boolean hasFocus) {
            if(!hasFocus)
                calculate();
        }
    });
CaptJak
  • 3,592
  • 1
  • 29
  • 50
Rich
  • 36,270
  • 31
  • 115
  • 154
  • OK, that works but only when the user clicks on something else. Is there a way to detect when the user presses done, too? EDIT: Or un-focus when the user presses done. – Matt Feb 24 '11 at 03:23
  • 1
    Yeah. Just have the EditText's OnFocusChangeListener and the Button's OnClickListener call the same calculate method. I edited my answer to include this code. ^ – Rich Feb 24 '11 at 11:35
  • Adding 'android:imeOptions="actionNext"' to txtEdit's xml made it lose focus when the soft-keyboard NextKey was pressed on my Samsung Galaxy. Adding 'txtEdit.setOnKeyListener(new OnKeyListener() {' to onCreate() made an emulator with no soft-keyboard respond to the EnterKey. – earlcasper Mar 13 '14 at 22:31
15

Using an EditText object xml defined like this:

    <EditText
        android:id="@+id/create_survey_newquestion_editText_minvalue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:ems="4"
        android:imeOptions="actionDone"
        android:inputType="number" />

We can capture its text i) when the user clicks the Done button on the soft keyboard (OnEditorActionListener) or ii) when the EditText has lost the user focus (OnFocusChangeListener) which now is on another EditText:

    /**
     * 3. Set the min value EditText listener
     */
    editText= (EditText) this.viewGroup.findViewById(R.id.create_survey_newquestion_editText_minvalue);
    editText.setOnEditorActionListener(new OnEditorActionListener()
    {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event)
        {
            String input;
            if(actionId == EditorInfo.IME_ACTION_DONE)
            {
                input= v.getText().toString();
                MyActivity.calculate(input);
                return true; // consume.
            }
            return false; // pass on to other listeners.
        }
    });
    editText.setOnFocusChangeListener(new View.OnFocusChangeListener()
    {
        @Override
        public void onFocusChange(View v, boolean hasFocus)
        {
            String input;
            EditText editText;

            if(!hasFocus)
            {
                editText= (EditText) v;
                input= editText.getText().toString();
                MyActivity.calculate(input);
            }
        }
    });

This works for me. You can hide the soft keyboard after made the calculations using a code like this:

private void hideKeyboard(EditText editText)
{
    InputMethodManager imm= (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}

Edit: added return values to onEditorAction

Brabbeldas
  • 1,939
  • 4
  • 20
  • 32
jsanmarb
  • 906
  • 12
  • 14
5

I have done this simple thing, when focus is shifted from edit text get the text. This will work if user shifts the focus to select other views like a button or other EditText or any view.

        editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                EditText editText = (EditText) v;
                String text = editText.getText().toString();
             }
        }
    });
Murli
  • 524
  • 6
  • 11
0

To be more highlevel you may use TextWatcher's afterTextChanged() method.

biegleux
  • 13,179
  • 11
  • 45
  • 52
user717593
  • 21
  • 2