1

I have a fragment containing an EditText for search input and a ListView. I've got the search part working, but now I want to close the keyboard when the user clicks the on the screen outside of the EditText. I'd also like to consume the click event (because it is a ListView, if I don't consume the click event the user may accidentally click on a ListView item they didn't want to open)

I know how to do this in an activity, but it seems to be different for fragments.

What I've tried so far:

  • Implement View.OnClickListener in the fragment and implement onClick as such:

    @Override
    public void onClick(View v) {
        System.out.println("onClick true");
        if (!(v instanceof EditText)) {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.
                    INPUT_METHOD_SERVICE);
            if (getActivity().getCurrentFocus() != null) {
                imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
            }
        }
    }
    

This never seemed to post "onClick true" when I clicked.

  • Override onTouchEvent in the fragment's activity and implement onTouchEvent as such:

    @Override
    public boolean onTouchEvent(final MotionEvent event) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.
                INPUT_METHOD_SERVICE);
        if (getCurrentFocus() != null) {
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
        return true;
    }
    

Any help would be greatly appreciated. Thanks in advance.

nbokmans
  • 5,151
  • 3
  • 33
  • 54

3 Answers3

9

Code to dismiss Softkeyboard is below:

public static void hideSoftKeyboard(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager)  activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

You can put it in Utility Class or if you are defining it within an activity, avoid the activity parameter, or call hideSoftKeyboard(this).

You can write a method that iterates through every View in your activity, and check if it is an instanceof EditText if it is not register a setOnTouchListener to that component and everything will fall in place. In case you are wondering how to do that, it is in fact quite simple. Here is what you do, you write a recursive method like the following.

public void setupUI(View view) {

    //Set up touch listener for non-text box views to hide keyboard.
    if(!(view instanceof EditText)) {

        view.setOnTouchListener(new OnTouchListener() {

            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard();
                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);

            setupUI(innerView);
        }
    }
}

Call this method after SetcontentView() with paramet as id of your view like:

RelativeLayoutPanel android:id="@+id/parent"> ... </RelativeLayout>

Then call `setupUI(findViewById(R.id.parent))

Reference : Hide keypad in android while touching outside Edit Text Area

Community
  • 1
  • 1
KishuDroid
  • 6,116
  • 4
  • 30
  • 46
6

try this,

in xml file

android:clickable="true" 
android:focusableInTouchMode="true" 

create method.

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

call method.

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            hideKeyboard(v);
        }
    }
});
Ganpat Kaliya
  • 1,234
  • 2
  • 9
  • 16
2

If I get you right you can try to use a OnFocusChangeListener:

yourEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            final InputMethodManager inputManager = (InputMethodManager) getAppContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            if (inputManager != null && !hasFocus) {
                inputManager.hideSoftInputFromWindow(currentFocusedView.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            }
        }
    });

This is just a sample, but maybe it points into the right direction.

Thomas R.
  • 7,850
  • 3
  • 29
  • 39