How to hide soft keyboard on android after clicking outside EditText?

前端 未结 30 1734
醉话见心
醉话见心 2020-11-22 11:46

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

InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hi         


        
相关标签:
30条回答
  • 2020-11-22 12:19

    This is a slightly modified version of fje's answer which mostly worked perfectly.

    This version uses ACTION_DOWN so performing a scroll action also closes the keyboard. It also doesn't propagate the event unless you click on another EditText. This means that clicking anywhere outside your EditText, even on another clickable, simply closes the keyboard.

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev)
    {
        if(ev.getAction() == MotionEvent.ACTION_DOWN)
        {
            final View view = getCurrentFocus();
    
            if(view != null)
            {
                final View viewTmp = getCurrentFocus();
                final View viewNew = viewTmp != null ? viewTmp : view;
    
                if(viewNew.equals(view))
                {
                    final Rect rect = new Rect();
                    final int[] coordinates = new int[2];
    
                    view.getLocationOnScreen(coordinates);
    
                    rect.set(coordinates[0], coordinates[1], coordinates[0] + view.getWidth(), coordinates[1] + view.getHeight());
    
                    final int x = (int) ev.getX();
                    final int y = (int) ev.getY();
    
                    if(rect.contains(x, y))
                    {
                        super.dispatchTouchEvent(ev);
                        return true;
                    }
                }
                else if(viewNew instanceof EditText || viewNew instanceof CustomEditText)
                {
                    super.dispatchTouchEvent(ev);
                    return true;
                }
    
                final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    
                inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);
    
                viewNew.clearFocus();
    
                return true;
            }
        }
        return super.dispatchTouchEvent(ev);
    }
    
    0 讨论(0)
  • 2020-11-22 12:22

    The following snippet simply hides the keyboard:

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

    You can put this up in a utility class, or if you are defining it within an activity, avoid the activity parameter, or call hideSoftKeyboard(this).

    The trickiest part is when to call it. 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, in fact you can use this to do anything, like setup custom typefaces etc... Here is the method

    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(MyActivity.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);
            }
        }
    }
    

    That is all, just call this method after you setContentView in your activity. In case you are wondering what parameter you would pass, it is the id of the parent container. Assign an id to your parent container like

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

    and call setupUI(findViewById(R.id.parent)), that is all.

    If you want to use this effectively, you may create an extended Activity and put this method in, and make all other activities in your application extend this activity and call its setupUI() in the onCreate() method.

    Hope it helps.

    If you use more than 1 activity define common id to parent layout like <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

    Then extend a class from Activity and define setupUI(findViewById(R.id.main_parent)) Within its OnResume() and extend this class instead of ``Activityin your program


    Here is a Kotlin version of the above function:

    @file:JvmName("KeyboardUtils")
    
    fun Activity.hideSoftKeyboard() {
        currentFocus?.let {
            val inputMethodManager = ContextCompat.getSystemService(this, InputMethodManager::class.java)!!
            inputMethodManager.hideSoftInputFromWindow(it.windowToken, 0)
        }
    }
    
    0 讨论(0)
  • 2020-11-22 12:24

    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.

    0 讨论(0)
  • 2020-11-22 12:24

    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.

    0 讨论(0)
  • 2020-11-22 12:24

    In kotlin, we can do the following. No need to iterate all the views. It will work for fragments also.

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
        currentFocus?.let {
            val imm: InputMethodManager = getSystemService(
                Context.INPUT_METHOD_SERVICE
            ) as (InputMethodManager)
            imm.hideSoftInputFromWindow(it.windowToken, 0)
        }
        return super.dispatchTouchEvent(ev)
    }
    
    0 讨论(0)
  • 2020-11-22 12:24

    This one is the easiest solution for me (and worked out by me).

    This is the method to hide the keyboard.

    public void hideKeyboard(View view){
            if(!(view instanceof EditText)){
                InputMethodManager inputMethodManager=(InputMethodManager)getSystemService(INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
            }
        }
    

    now set onclick attribute of the parent layout of the activity to above method hideKeyboard either from the Design view of your XML file or writing below code in Text view of your XML file.

    android:onClick="hideKeyboard"
    
    0 讨论(0)
提交回复
热议问题