【问题标题】:hide default keyboard on click in android在android中单击时隐藏默认键盘
【发布时间】:2016-05-27 14:58:19
【问题描述】:

当我单击屏幕中编辑框的外侧时,我想隐藏软键盘。我该怎么做?

【问题讨论】:

  • 它应该自动完成。只要你点击某个不会弹出键盘的地方
  • @Falmarri 最初我认为你是对的,但我无法在我的测试应用程序上实现这一点。测试场景:1)点击一个EditText-view,它会弹出键盘,2)点击同一个片段中的一个SeekBar 3)点击一个带有focusable = true的RadioButton。 2 和 3 都没有关闭键盘。这种建议的行为是否记录在任何地方?

标签: android


【解决方案1】:

必须对其进行编辑才能使其正常工作。添加了一个检查以查看焦点视图是否为 EditText。

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    View v = getCurrentFocus();
    boolean ret = super.dispatchTouchEvent(event);

    if (v instanceof EditText) {
        View w = getCurrentFocus();
        int scrcoords[] = new int[2];
        w.getLocationOnScreen(scrcoords);
        float x = event.getRawX() + w.getLeft() - scrcoords[0];
        float y = event.getRawY() + w.getTop() - scrcoords[1];

        Log.d("Activity", "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]);
        if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) { 

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

可能会以更流畅的方式完成,但效果非常好。

【讨论】:

  • 补充一点说明 - 如果您希望在用户单击 EDITTEXT 之外的任何位置时关闭键盘,而不仅仅是在另一个按钮的 onClick() 中,那么 Daniel 的代码可以完美运行。只需将方法添加/覆盖到您的 Activity 中,用户就可以通过单击 EditText 之外的任何位置来关闭键盘(也适用于单个屏幕上的多个 EditText)。谢谢丹尼尔!
  • 这不是一个完美的答案,因为它会在触摸时隐藏键盘,而不是点击。如果你例如滚动一下,键盘将被隐藏。这通常是不想要的。
  • @Daniel,@kyle Clegg,@lxx,@bibangamba,我正在使用他的代码,它运行良好,但它会导致屏幕闪烁,如果有大约 15-20 的编辑文本并且滚动到底部从一个专注的编辑文本(打字时),你来到了相同的位置,你正在打字,屏幕闪烁,所以请帮我解决这个问题。
【解决方案2】:

要强制隐藏键盘,您可以使用以下代码...我将它放在一个名为“hideSoftKeyboard()”的方法中。正如 Falmarri 所提到的,当您点击软键盘时,应该隐藏自己。但是,如果您在另一个项目的 'onClick()' 中调用此方法,它将强制关闭键盘。

private void hideSoftKeyboard(){
    if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(yourEditTextHere.getWindowToken(), 0);
    }
}

【讨论】:

    【解决方案3】:

    这可以使用以下代码来完成:

    1) 使用 findViewById() 将父布局引用到 java 代码中。

    2) 然后对其应用 setOnTouchListener()。

    3) 在 onTouchMethod() 中添加如下代码。

     lin = (LinearLayout) findViewById(R.id.lin);
        lin.setOnTouchListener(new OnTouchListener() 
        {
            @Override
            public boolean onTouch(View v, MotionEvent event) 
            {
                   InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                                   imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
                           return false;
            }
        });
    

    【讨论】:

      【解决方案4】:

      我将以下内容添加到我的活动中。它之所以有效,是因为在 Focusable View 之外触摸不会改变焦点(因此 w == v),但触摸将在 View 的矩形之外。

      public boolean dispatchTouchEvent(MotionEvent event) {
          View v = getCurrentFocus();
          boolean ret = super.dispatchTouchEvent(event);
          View w = getCurrentFocus();
          int scrcoords[] = new int[2];
          w.getLocationOnScreen(scrcoords);
          float x = event.getRawX() + w.getLeft() - scrcoords[0];
          float y = event.getRawY() + w.getTop() - scrcoords[1];
      
          Log.d("Activity", "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]);
          if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) { 
              inputManager.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
          }
          return ret;
      
      }
      

      [编辑:修复小错误]

      【讨论】:

        【解决方案5】:

        作为已接受答案的补充。

        如果接受的答案不适合您,您可以将hideSoftKeyboard() 方法添加到您的EditTextonClickListeneronClick() 方法中。例如:

        editText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                hideSoftKeyboard();
            }
        });
        

        (将以上代码放在onResume()或其他地方)

        ps。 hideSoftKeyboard()的定义

        private void hideSoftKeyboard(){
            if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){
                InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
            }
        }
        

        【讨论】:

          【解决方案6】:
          public boolean OutsideTouchEvent(MotionEvent m_event) {
              View v = getCurrentFocus();
              boolean value = super.dispatchTouchEvent(m_event);
              View w = getCurrentFocus();
              int scrcoords[] = new int[2];
              w.getLocationOnScreen(scrcoords);
              float x = m_event.getRawX() + w.getLeft() - scrcoords[0];
              float y = m_event.getRawY() + w.getTop() - scrcoords[1];
          
              if (m_event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom()) ) { 
                  InputMethodManager inputMethodManager = (InputMethodManager)  YourActivity.this.getSystemService(Activity.INPUT_METHOD_SERVICE);
                  inputMethodManager.hideSoftInputFromWindow(YourActivity.this.getCurrentFocus().getWindowToken(), 0);
              }
              return value;
          
          }
          

          【讨论】:

            【解决方案7】:

            将 inputType 设置为零以编辑文本
            editText.setInputType(0);

            这对我有用

            【讨论】:

              【解决方案8】:

              首先感谢 Daniel,他的代码非常好,我用了一段时间。

              最近我意识到我必须改进它。问题是滚动页面。我的项目中有很多EditTexts,当你滚动页面时它隐藏了键盘。

              我想出了一个使用onGestureListener 而不是覆盖dispatchTouchEvent. 的解决方案

              public class TabActivity extends ActionBarActivity implements GestureDetector.OnGestureListener {
              
                  public void onCreate(Bundle savedInstanceState) {
                      super.onCreate(savedInstanceState);
                      ...
                      ...
                      gestureScanner = new GestureDetector(TabActivity.this,this);
                  }
              
                  @Override
                  public boolean dispatchTouchEvent(MotionEvent ev) {
                      gestureScanner.onTouchEvent(ev);
                      return super.dispatchTouchEvent(ev);
                  }
              
                  @Override
                  public boolean onSingleTapUp(MotionEvent event) {
                      View v = getCurrentFocus();
              
                      if (v instanceof EditText) {
                          View w = getCurrentFocus();
                          int scrcoords[] = new int[2];
                          w.getLocationOnScreen(scrcoords);
                          boolean hide = true;
              
                          View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);
                          ArrayList<View> editTexts = view.getFocusables(0);     // Get All EditTexts in view
              
                          for(int i=0; i< editTexts.size(); i++){
                              View editText = editTexts.get(i);
                              editText.getLocationOnScreen(scrcoords);
                              float x = event.getRawX();
                              float y = event.getRawY();
                              int viewX = scrcoords[0];
                              int viewY = scrcoords[1];
              
                              // If touch is in any of EditText, keep keyboard active, otherwise hide it.
                              if (event.getAction() == MotionEvent.ACTION_UP  && ( x > viewX && x < (viewX + editText.getWidth())) && ( y > viewY && y < (viewY + editText.getHeight())) ) {
                                  hide = false;
                              }
                          }
              
                          if (hide) {
                              InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                              imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
                          }
                      }
                      return true;
                  }
              
                  @Override
                  public boolean onScroll(MotionEvent event, MotionEvent e2, float distanceX, float distanceY) {
                      return true;
                  }     
              }
              

              所以,如果用户滚动页面,它会转到onScroll 方法,它什么也不做。如果用户只是触摸屏幕,则会触发onSingleTapUp 方法。

              我还必须更改 Daniel 代码的 if 语句。 Daniel 正在检查触摸事件是否在EditText 之外。由于我有很多EditViews,我更改了代码以查找触摸事件是否在EditTexts 中。

              它对我来说很好,如果有任何改进或错误,请告诉我。

              【讨论】:

              • 查看视图 = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0);我没有得到这个。你能解释一下吗?
              • 那是我从事的一个老项目,我不记得细节了。基本上,我在那里做的是检索父视图。 android.R.id.content 将为您提供根视图。 getChildAt(0) 可能用于检索我的 EditTexts 的父级。
              • 所以你的意思是在视图组或视图内添加所有编辑文本?
              • 您的情况可能不同。就我而言,我所有的EditTexts 都在LinearLayout 中。所以view 是我的LinearLayout,所以我在那个LinearLayout 中检索所有EditTexts。你想达到什么目的?
              • 在我的例子中,所有的编辑文本也都是线性布局。当我点击提交按钮时,应该隐藏虚拟键盘。!
              【解决方案9】:

              只要像这样将输入类型设置为 null

              editText.setInputType(InputType.TYPE_NULL);

              【讨论】:

                【解决方案10】:

                我得到了一个很好的解决方案。我知道它为时已晚,但大多数时候在搜索时将此链接作为第一个链接。所以它可能对其他人有帮助。如果您单击任何文本/按钮,它将隐藏已经可见的软键盘。

                date.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            // Hide soft keyboard
                       InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
                            imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
                
                      // here i am showing the Date Dialog. one can proceed with their functionality
                
                            //show date picker dialog
                            showDialog(Date_DIALOG_ID);
                        }
                    });
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2022-01-18
                  • 2013-05-05
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-11-15
                  • 2013-03-03
                  • 2020-10-15
                  • 1970-01-01
                  相关资源
                  最近更新 更多