hide keyboard in fragment on outside click

2020-02-26 11:29发布

问题:

I have a fragment containing an EditText for input, but now I want to close the keyboard when the user clicks on the screen outside of the EditText.

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

i am calling this method on view.onTouchListener

public static void hideSoftKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);

inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}

anyone have solution, thanks

回答1:

In the parent Activity of the fragment override the following method:

 @Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        View v = getCurrentFocus();
        if ( v instanceof EditText) {
            Rect outRect = new Rect();
            v.getGlobalVisibleRect(outRect);
            if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                v.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

And in the layout of the fragment use this attribute:

android:focusableInTouchMode="true"

Hope this will help you.



回答2:

Use this method its works fine

public static void hideKeyBoardMethod(final Context con, final View view) {
        try {
            view.post(new Runnable() {
                @Override
                public void run() {
                    InputMethodManager imm = (InputMethodManager) con.getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                }
            });

        } catch (Exception e) {
            e.printStackTrace();
        }
    }


回答3:

You could use this method is working fine for me. Just pass the reference of the root element of your layout like this

setupUI(rootView.findViewById(R.id.rootParent))

code for the setupUI is below..

public void setupUI(View parentView) {

    //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 v, MotionEvent event) {
                hideSoftKeyboard();
                handleCallBack();
                return false;
            }
        });
    }


回答4:

You can also do like this

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

Hope it help!



回答5:

If you want Touch outside of editText then Keyboard hide automatic so use this code

public boolean dispatchTouchEvent(MotionEvent event) {

        View view = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(event);

        if (view instanceof EditText) {
            View w = getCurrentFocus();
            int location[] = new int[2];
            w.getLocationOnScreen(location);
            float x = event.getRawX() + w.getLeft() - location[0];
            float y = event.getRawY() + w.getTop() - location[1];
            if (event.getAction() == MotionEvent.ACTION_DOWN
                    && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) {
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
            }
        }
        return ret;
    }


回答6:

In case of Fragment use below code

View view = inflater.inflate(R.layout.fragment_test, container, false);

    view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {

                if(event.getAction() == MotionEvent.ACTION_MOVE){
                    dispatchTouchEvent(event);
                }
                return true;
            }
    });

//here the rest of your code

return view;

Apply this code and call dispatchTouchEvent(); method



回答7:

i just overrided dispatchTouchEvent() Method in all the fragments of the activity.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    // TODO Auto-generated method stub
     if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if ( v instanceof EditText) {
                Rect outRect = new Rect();
                v.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int)ev.getRawX(), (int)ev.getRawY())) {
                    v.clearFocus();
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        } 

and set property in every XML of fragment in Main Layout

android:focusableInTouchMode="true"