How to hide soft keyboard on android after clickin

2018-12-31 14:48发布

Ok everyone knows that to hide a keyboard you need to implement:

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

But the big deal here is how to hide the keyboard when the user touches or selects any other place that is not an EditText or the softKeyboard?

I tried to use the onTouchEvent() on my parent Activity but that only works if user touches outside any other view and there is no scrollview.

I tried to implement a touch, click, focus listener without any success.

I even tried to implement my own scrollview to intercept touch events but I can only get the coordinates of the event and not the view clicked.

Is there a standard way to do this?? in iPhone it was really easy.

30条回答
孤独总比滥情好
2楼-- · 2018-12-31 15:18

I have refined the method, put the following code in some UI utility class(preferably, not necessarily) so that it can be accessed from all your Activity or Fragment classes to serve its purpose.

public static void serachAndHideSoftKeybordFromView(View view, final Activity act) {
    if(!(view instanceof EditText)) {
        view.setOnTouchListener(new View.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(act);
                return false;
            }
        });
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View nextViewInHierarchy = ((ViewGroup) view).getChildAt(i);
            serachAndHideSoftKeybordFromView(nextViewInHierarchy, act);
        }
    }
}
public static void hideSoftKeyboard (Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

Then say for example you need to call it from activity, call it as follows;

UIutils.serachAndHideSoftKeybordFromView(findViewById(android.R.id.content), YourActivityName.this);

Notice

findViewById(android.R.id.content)

This gives us the root view of the current group(you mustn't have set the id on root view).

Cheers :)

查看更多
旧时光的记忆
3楼-- · 2018-12-31 15:19

Activity

 @Override
 public boolean dispatchTouchEvent(MotionEvent ev) {
     ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
     return super.dispatchTouchEvent(ev);
 }

ScreenUtils

 public static void hideKeyboard(Context context, IBinder windowToken) {
     InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
 }
查看更多
大哥的爱人
4楼-- · 2018-12-31 15:20

I find the accepted answer a bit complicated.

Here's my solution. Add an OnTouchListener to your main layout, ie.:

findViewById(R.id.mainLayout).setOnTouchListener(this)

and put the following code in the onTouch method.

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

This way you don't have to iterate over all views.

查看更多
梦该遗忘
5楼-- · 2018-12-31 15:21

To solve this problem what you have to do is first use setOnFocusChangeListener of that Edittext

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    Log.d("focus", "focus loosed");
                    // Do whatever you want here
                } else {
                    Log.d("focus", "focused");
                }
            }
        });

and then what you need to do is override dispatchTouchEvent in the activity which contains that Edittext see below code

@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())) {
                Log.d("focus", "touchevent");
                v.clearFocus();
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
            }
        }
    }
    return super.dispatchTouchEvent(event);
}

Now what will happen is when a user click outside then firstly this dispatchTouchEvent will get called which then will clear focus from the editext now your OnFocusChangeListener will get called that focus has been changed now here you can do anything which you wanted to do hope it works

查看更多
柔情千种
6楼-- · 2018-12-31 15:22

I find the accepted answer bit complex for this simple requirement. Here's what worked for me without any glitch.

findViewById(R.id.mainLayout).setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            return false;
        }
    });
查看更多
墨雨无痕
7楼-- · 2018-12-31 15:23

Plea: I recognize I have no clout, but please take my answer seriously.

Problem: Dismiss soft keyboard when clicking away from keyboard or edit text with minimal code.

Solution: External library known as Butterknife.

One Line Solution:

@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }

More Readable Solution:

@OnClick(R.id.activity_signup_layout) 
public void closeKeyboard() {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

Explanation: Bind OnClick Listener to the activity's XML Layout parent ID, so that any click on the layout (not on the edit text or keyboard) will run that snippet of code which will hide the keyboard.

Example: If your layout file is R.layout.my_layout and your layout id is R.id.my_layout_id, then your Butterknife bind call should look like:

(@OnClick(R.id.my_layout_id) 
public void yourMethod {
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

Butterknife Documentation Link: http://jakewharton.github.io/butterknife/

Plug: Butterknife will revolutionize your android development. Consider it.

Note: The same result can be achieved without the use of external library Butterknife. Just set an OnClickListener to the parent layout as described above.

查看更多
登录 后发表回答