Android 在失去焦点时隐藏软键盘

Android 在失去焦点时隐藏软键盘,android,Android,当我们有一个EditText并且它失去了焦点(对于一个不需要键盘的元素),软键盘应该自动隐藏还是我们应该自己隐藏它 我将焦点从一个自动完成搜索视图(我猜它的行为应该像一个编辑文本)移动到一个按钮,请求焦点()返回true,但键盘没有隐藏 Android不会为您隐藏键盘。如果您想在EditText失去焦点时隐藏键盘,请尝试在该事件中使用如下方法: private void hideKeypad() { EditText edtView = (EditText) findViewById(R

当我们有一个
EditText
并且它失去了焦点(对于一个不需要键盘的元素),软键盘应该自动隐藏还是我们应该自己隐藏它


我将焦点从一个
自动完成搜索视图
(我猜它的行为应该像一个
编辑文本
)移动到一个
按钮
请求焦点()返回true,但键盘没有隐藏

Android不会为您隐藏键盘。如果您想在
EditText
失去焦点时隐藏键盘,请尝试在该事件中使用如下方法:

private void hideKeypad() {
    EditText edtView = (EditText) findViewById(R.id.e_id);

    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(edtView.getWindowToken(), 0);
}

试试这个,也许它会解决你的问题

private void hideKeyboard() {
    InputMethodManager mImMan = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    mImMan.hideSoftInputFromWindow(mYourEdttxtName.getWindowToken(), 0);
}

您可以在

中找到更多信息。最好的方法是为EditText设置一个OnFocusChangeListener,然后将代码添加到键盘的OnFocusChange方法中。当编辑文本失去焦点时,Android会自动关闭键盘

在OnCreate方法中类似于以下内容:

EditText editText = (EditText) findViewById(R.id.textbox);
OnFocusChangeListener ofcListener = new MyFocusChangeListener();
editText.setOnFocusChangeListener(ofcListener);
然后添加类:

private class MyFocusChangeListener implements OnFocusChangeListener {

    public void onFocusChange(View v, boolean hasFocus){

        if(v.getId() == R.id.textbox && !hasFocus) {

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

        }
    }
}
试试这个

 /**
 * Hide keyboard on touch of UI
 */
public void hideKeyboard(View view) {

    if (view instanceof ViewGroup) {

        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {

            View innerView = ((ViewGroup) view).getChildAt(i);

            hideKeyboard(innerView);
        }
    }
    if (!(view instanceof EditText)) {

        view.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                hideSoftKeyboard(v);
                return false;
            }

        });
    }

}

/**
 * Hide keyboard while focus is moved
 */
public void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) contentsContext_
                .getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            if (android.os.Build.VERSION.SDK_INT < 11) {
                inputManager.hideSoftInputFromWindow(view.getWindowToken(),
                        0);
            } else {
                if (this.getCurrentFocus() != null) {
                    inputManager.hideSoftInputFromWindow(this
                            .getCurrentFocus().getWindowToken(),
                            InputMethodManager.HIDE_NOT_ALWAYS);
                }
                view.clearFocus();
            }
            view.clearFocus();
        }
    }
}
/**
*触摸UI时隐藏键盘
*/
公共无效隐藏板(视图){
if(视图组的视图实例){
对于(int i=0;i<((视图组)视图)。getChildCount();i++){
视图内部视图=((视图组)视图);
隐藏板(内部视图);
}
}
如果(!(查看EditText的实例)){
view.setOnTouchListener(新的OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
隐藏键盘(v);
返回false;
}
});
}
}
/**
*移动焦点时隐藏键盘
*/
公用无效隐藏键盘(视图){
如果(视图!=null){
InputMethodManager inputManager=(InputMethodManager)内容上下文_
.getSystemService(Context.INPUT\u方法\u服务);
如果(inputManager!=null){
if(android.os.Build.VERSION.SDK_INT<11){
inputManager.hideSoftInputFromWindow(view.getWindowToken(),
0);
}否则{
if(this.getCurrentFocus()!=null){
inputManager.hideSoftInputFromWindow(此
.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE(不总是);
}
view.clearFocus();
}
view.clearFocus();
}
}
}

您可以覆盖
dispatchTouchEvent
方法来实现它:

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    if (event.getAction() == MotionEvent.ACTION_DOWN) {

        /**
         * It gets into the above IF-BLOCK if anywhere the screen is touched.
         */

        View v = getCurrentFocus();
        if ( v instanceof EditText) {


            /**
             * Now, it gets into the above IF-BLOCK if an EditText is already in focus, and you tap somewhere else
             * to take the focus away from that particular EditText. It could have 2 cases after tapping:
             * 1. No EditText has focus
             * 2. Focus is just shifted to the other 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 );
}
奖励:如果EditText获得焦点,则触发事件的顺序为:

  • 调用另一个EditText的
    onFocusChange()
    (如果另一个EditText失去焦点)
  • ACTION\u DOWN
    被调用
  • 最后,将调用该EditText的
    onFocusChange()
    方法

  • 我的问题用这段代码解决了(在片段中)

    隐藏板

     public void hideKeyBoard(View v)
    {
        InputMethodManager imm=(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
    }
    

    已找到此问题的解决方案。
    它在活动上使用DispatchTouchEvent,并且不会将每个EditText挂接到FocusChange或Touch事件。
    这是更好的解决方案。

    我的Xamarin实现如下所示:

    public override bool DispatchTouchEvent(MotionEvent ev)
        {
            if (ev.Action == MotionEventActions.Down)
            {
                var text = CurrentFocus as EditText;
                if (text != null)
                {
                    var outRect = new Rect();
                    text.GetGlobalVisibleRect(outRect);
                    if (outRect.Contains((int) ev.RawX, (int) ev.RawY)) return base.DispatchTouchEvent(ev);
                    text.ClearFocus();
                    HideSoftKeyboard();
                }
            }
            return base.DispatchTouchEvent(ev);
        }
    
    protected void HideSoftKeyboard()
        {
            var inputMethodManager = (InputMethodManager) GetSystemService(InputMethodService);
            inputMethodManager.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);
        }
    

    只需创建一个静态方法

    public static void touchScreenAndHideKeyboardOnFocus(View view, final Activity activity) {
    
        if (view instanceof EditText) {
            view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (!hasFocus) {
                        if(activity != null) {
                           InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
                           if (activity.getCurrentFocus() != null) {
                              inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
                           }
                        }
                    }
                }
            });
        }
    
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                View innerView = ((ViewGroup) view).getChildAt(i);
                touchScreenAndHideKeyboardOnFocus(innerView, activity);
            }
        }
    }
    
    公共静态无效触摸屏和HidekeyboardonFocus(视图、最终活动){
    如果(查看EditText的实例){
    view.setOnFocusChangeListener(新视图.OnFocusChangeListener(){
    @凌驾
    public void onFocusChange(视图v,布尔hasFocus){
    如果(!hasFocus){
    if(活动!=null){
    InputMethodManager InputMethodManager=(InputMethodManager)activity.getSystemService(activity.INPUT\u方法\u服务);
    if(activity.getCurrentFocus()!=null){
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(),inputMethodManager.HIDE_不总是);
    }
    }
    }
    }
    });
    }
    if(视图组的视图实例){
    对于(int i=0;i<((视图组)视图)。getChildCount();i++){
    视图内部视图=((视图组)视图);
    触摸屏和HidekeyBoardonFocus(内部视图、活动);
    }
    }
    }
    
    视图是布局的根视图。。但是要小心,如果您的edittext中有另一个焦点侦听器..

    这对我很有用:

    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    

    只是想在一堆答案中添加一个Kotlin简化版:

    // onCreateView of the Fragment
    myAutocompleteText.apply {
        setAdapter(adapter) // whatever the adapter is
        setOnFocusChangeListener { _, hasFocus ->
            if (hasFocus) requireActivity().closeKeyboard() // if called from an Activity instead of a Fragment, just replace it's reference instead of requireActivity()
        }
    }
    
    
    /**
     * Hides the keyboard if possible.
     */
    object KeyboardUtils {
        fun Activity.hideKeyboard() {
            if (currentFocus != null) {
                (getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
            }
        }
    }
    

    我有,这就是我问的原因。@抗坏血酸不要弄糟它安卓会处理这件事的。。是的,好吧,在我的情况下不会。你是问他是否尝试做一些事情,而你只是说它应该自动完成?然后必须为应用程序上的每个editText组件完成?没有任何全局设置来定义此行为吗?如果没有,并且应用程序中有许多editText,我建议扩展editText类,将侦听器添加到扩展类中,并在应用程序中使用修改过的类。如何自动创建?如果我有150到25张表格,我不想每次都这么做。。。这个特性应该很明显,我必须在根视图中添加以下内容(在片段中):rootView.setFocusable(true);setFocusableInTouchMode(true);rootView.setClickable(true);什么是“强迫”?你救了我的命!我只是复制了它,它工作了!
    // onCreateView of the Fragment
    myAutocompleteText.apply {
        setAdapter(adapter) // whatever the adapter is
        setOnFocusChangeListener { _, hasFocus ->
            if (hasFocus) requireActivity().closeKeyboard() // if called from an Activity instead of a Fragment, just replace it's reference instead of requireActivity()
        }
    }
    
    
    /**
     * Hides the keyboard if possible.
     */
    object KeyboardUtils {
        fun Activity.hideKeyboard() {
            if (currentFocus != null) {
                (getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
            }
        }
    }