Search code examples
androidandroid-edittextandroid-scrollview

How to clear focus of multiple EditText fields in a ScrollView efficiently?


I have the following code:

public void hideKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

public void setupDialog(View view) {
    // Set up touch listener for non-text box views to hide keyboard.
    if (!(view instanceof EditText)) {
        view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View view, MotionEvent event) {
                hideKeyboard(view);
                return false;
            }
        });
    }

    //If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupDialog(innerView);
        }
    }
}

public void setupEditTextFocusChangedListeners(View view) {
    if (view instanceof EditText) {
        view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View view, boolean hasFocus) {
                if (hasFocus) {
                    ((EditText) view).setSelection(((EditText) view).getText().length());
                }
            }
        });
    }

    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupEditTextFocusChangedListeners(innerView);
        }
    }
}

While the keyboard hides as it should when clicking or scrolling outside of any of the EditText fields, when scrolling the EditText still retains focus even though the keyboard does dismiss.

The EditText fields are in a table format. I know I could call clearFocus() on each EditText individually in hideKeyboard, but that doesn't seem like it would be efficient. Is there a more efficient way to clear the focus of the EditText when scrolling?


Solution

  • As only one EditText can be focused and you have onFocused listener you can:

     private Edittext focused;
    public void onFocusChange(View view, boolean hasFocus) {
                if (hasFocus) {
                    ((EditText) view).setSelection(((EditText) view).getText().length());
             focused =  view
      }
    }
    

    And then in hideKeyboard():

    public void hideKeyboard(View view) {
    InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
    focused.clearFocus();
    }