hide keyboard when user taps anywhere else on the

2019-01-21 10:58发布

问题:

I need to hide the softkeypad in android when user click on anywhere other than a Edittext. There are many help for iphone but not for android. I tried this code but its not working :(

final RelativeLayout base = (RelativeLayout) findViewById(R.id.RelativeLayout1);

    findViewById(R.id.base).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(base.getWindowToken(), 0);

        }
    });

Thanks in advance !

回答1:

You can use the onTouchEvent() to hide the Softkeyboard.

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

Though this solution works, but the best I would suggest is to use below answer as it gives best solution of closing the keyboard touching anywhere else then EditText.



回答2:

Well I have done this way:

Add code in your Activity.

This would work for Fragment also, no need to add this code in Fragment.

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    View view = getCurrentFocus();
    if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        view.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + view.getLeft() - scrcoords[0];
        float y = ev.getRawY() + view.getTop() - scrcoords[1];
        if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
        ((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
    }
    return super.dispatchTouchEvent(ev);
}

Hope this will help you.



回答3:

The best work around I found was using as below,

Override dispatchTouchEvent() and try to get the area of EditText using Rect

 @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
         int x = (int) ev.getX();
         int y = (int) ev.getY();

         if (ev.getAction() == MotionEvent.ACTION_DOWN &&
             !getLocationOnScreen(etFeedback).contains(x, y)) {
             InputMethodManager input = (InputMethodManager) 
                                   activity.getSystemService(Context.INPUT_METHOD_SERVICE);
             input.hideSoftInputFromWindow(etFeedback.getWindowToken(), 0);
         }

        return super.dispatchTouchEvent(ev);
    }

Method that caculates 4 corner of View(here its EditText)

protected Rect getLocationOnScreen(EditText mEditText) {
        Rect mRect = new Rect();
        int[] location = new int[2];

        mEditText.getLocationOnScreen(location);

        mRect.left = location[0];
        mRect.top = location[1];
        mRect.right = location[0] + mEditText.getWidth();
        mRect.bottom = location[1] + mEditText.getHeight();

        return mRect;
    }

By using above code we can detect the area of EditText and we can check if the touch on the screen is part of the area of EditText or not. If its part of EditText then don't do anything let the touch do its job, and if the touch doesn't contain area of EditText then just close the softkeyboard.

******EDIT******

I just found another approach if we don't want to give any EditText as input and want to hide keyboard inside whole application when user touches anywhere else other than EditText. Then you have to create an BaseActivity and write global code for hiding keyboard as below,

 @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        boolean handleReturn = super.dispatchTouchEvent(ev);

        View view = getCurrentFocus();

         int x = (int) ev.getX();
         int y = (int) ev.getY();

         if(view instanceof EditText){
             View innerView = getCurrentFocus();

             if (ev.getAction() == MotionEvent.ACTION_UP && 
                                    !getLocationOnScreen(innerView).contains(x, y)) {

                 InputMethodManager input = (InputMethodManager) 
                                  getSystemService(Context.INPUT_METHOD_SERVICE);
                 input.hideSoftInputFromWindow(getWindow().getCurrentFocus()
                                                                 .getWindowToken(), 0);
             }
         }

        return handleReturn;
    }


回答4:

I tried this to hide Keyboard. You need to pass the method in your Layout file.

public void setupUI(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 v, MotionEvent event) {
                hideSoftKeyboard(LOGSignUpActivity.this);
                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);
        }
    }
}


回答5:

Call this method in your MainAcitivity.class

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


回答6:

For those who are looking for a Xamarin code for this, here you go :

  public override bool DispatchTouchEvent(MotionEvent ev)
    {
        try
        {
            View view = CurrentFocus;
            if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("android.webkit."))
            {
                int[] Touch = new int[2];
                view.GetLocationOnScreen(Touch);
                float x = ev.RawX + view.Left - Touch[0];
                float y = ev.RawY + view.Top - Touch[1];
                if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom)
                    ((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0);
            }
        }
        catch (System.Exception ex)
        {

        }

        return base.DispatchTouchEvent(ev);
    }