【问题标题】:Hiding softkeyboard reliably可靠地隐藏软键盘
【发布时间】:2012-10-23 14:12:32
【问题描述】:

我有一个应用程序,需要在相当多的操作上关闭软键盘。例如,当点击一个按钮,当一个新的布局被绘制,当屏幕方向改变,当控制器告诉 strong> UI 等等。 我使用 optionsMenuButton 通过 ViewFlipper 翻转视图,显然我希望键盘隐藏在翻转视图中(那里没有输入字段)。

到目前为止,我已经尝试过这些方法,并说明为什么这些方法不可靠:

这个没有用,因为我有很多编辑文本和其他视图。如果可能的话,我需要一个更通用的,一个不需要视图作为参数的。

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

这个对我根本不起作用:

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

这个可以,但是当视图翻转时会立即再次弹出键盘。

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

这个有时有效,但 getCurrentFocus() 大部分时间返回 null。

InputMethodManager inputManager = (InputMethodManager)            
Context.getSystemService(Context.INPUT_METHOD_SERVICE); 
inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(),      
InputMethodManager.HIDE_NOT_ALWAYS);

这个只有在显示键盘时才有效:

getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

这个不像第一段代码那样与 EditText 一起工作,而是与根布局一起工作,它会随着方向变化和每次调用 oncreate 时发生变化。对于横向/纵向和普通/大,我有不同的布局 XML。所有根布局的 ID 为 root。这第一次很好用,但之后就不行了。

InputMethodManager inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(findViewById(R.id.root).getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

底线:我尝试了很多软键盘隐藏方法,但它们似乎都不能可靠地工作。 是否有任何方法可以可靠地隐藏软键盘?

【问题讨论】:

    标签: java android android-softkeyboard


    【解决方案1】:

    我认为,如果您处理 getCurrentFocus() 的 null 情况,您就可以开始了。我使用下面的方法,它就像一个魅力!

         /* Hide Keyboard */
        public static void hideKeyboard(Activity activity){
            InputMethodManager inputMethodManager = (InputMethodManager)activity
                    .getSystemService(Context.INPUT_METHOD_SERVICE);
            View focus = activity.getCurrentFocus();
            if(focus != null)
                inputMethodManager.hideSoftInputFromWindow(focus.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    

    【讨论】:

    • 使用 viewflipper 时,视图焦点为空,因此键盘没有隐藏。 viewFlipper 可能有问题?编辑:可能不会,旋转屏幕也不会隐藏键盘
    • 您确定您传递了正确的活动并在正确的位置调用该方法吗?如果键盘打开,我认为 View focus 不应该为空。
    【解决方案2】:

    由于您需要EditText 来调出键盘,因此请找到特定的并使用您显示的第一种方法来隐藏键盘:

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

    但是,您将需要 EditText。首先,获取所有视图:

    public static ArrayList<View> getAllViewsFromRoots(View...roots) {
        ArrayList<View> result = new ArrayList<View>();
        for (View root : roots) {
            getAllViews(result, root);
        }
        return result;
    }
    
    private static void getAllViews(ArrayList<View> allviews, View parent) {
        allviews.add(parent);
        if (parent instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup)parent;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                getAllViews(allviews, viewGroup.getChildAt(i));
            }
        }
    }
    

    然后,获取可见的EditText

    public static EditText getEditText(View root) {
        ArrayList<View> views = getAllViewsFromRoots(root);
        for (View view : views) {
            if (view instanceof EditText && view.getVisibility() == View.VISIBLE) {
                return (EditText) view;
            }
        }
        return null;
    }
    

    在某处打电话:

    Toolkit.getEditText(((ViewParent) findViewById(android.R.id.content)).getChildAt(0));
    

    这样,调用隐藏方法。

    【讨论】:

    • 经过一番测试,这似乎是最可靠的方法。
    • 你能发送代码示例吗?我应该把 Toolkit.getEditText(((ViewParent)findViewById(android.R.id.content)).getChildAt(0)); ?
    • 嫁给我!!我一直在寻找一个好的解决方案。似乎我找到了一个不错(而且很短)的。谢谢!
    【解决方案3】:

    这个总是对我有用:

    InputMethodManager im = (InputMethodManager) getSystemService(MyActivity.INPUT_METHOD_SERVICE);
    im.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    

    【讨论】:

      【解决方案4】:

      科特林。把它放在常见的 BaseActivity 上。只需在活动中的任何位置调用 hideKeyboard() 方法,类似适用于 Fragment。

      open class BaseActivity : AppCompatActivity() {
      
      fun Fragment.hideKeyboard() {
          view?.let { activity?.hideKeyboard(it) }
      }
      
      fun Context.hideKeyboard(view: View) {
          val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
          inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
      }
      
      }
      

      【讨论】:

        【解决方案5】:

        只有这个解决方案对我有用:

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

        我有一个带有输入字段的对话框,隐藏对话框并没有隐藏平板电脑上的键盘。

        【讨论】:

          【解决方案6】:

          这应该适用于大多数情况。

          InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
          imm.hideSoftInputFromWindow(new View(this).getWindowToken(), 0);
          

          也无需担心空指针。

          【讨论】:

            【解决方案7】:

            试试这个:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-12-14
              • 2023-01-09
              • 2011-02-17
              • 2016-07-03
              • 2016-02-01
              相关资源
              最近更新 更多