代码之家  ›  专栏  ›  技术社区  ›  htafoya

在android上点击外部EditText后如何隐藏软键盘?

  •  308
  • htafoya  · 技术社区  · 14 年前

    好吧,每个人都知道要隐藏键盘,您需要实现:

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

    但这里最重要的是,当用户触摸或选择任何其他不是键盘的地方时,如何隐藏键盘 EditText 还是软键盘?

    onTouchEvent() 在我父母身上 Activity 但只有当用户接触到任何其他视图之外并且没有scrollview时,这才起作用。

    我甚至尝试实现自己的scrollview来拦截触摸事件,但我只能获取事件的坐标,而不能获取单击的视图。

    38 回复  |  直到 8 年前
        1
  •  559
  •   Navneeth G    8 年前

    以下代码片段仅隐藏键盘:

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

    您可以将其放在实用程序类中,或者如果在活动中定义它,请避免使用活动参数,或者调用 hideSoftKeyboard(this) .

    View 在你的活动中,检查它是否 instanceof EditText setOnTouchListener 所有的东西都会就位。如果你想知道怎么做,其实很简单。这是你要做的,你写一个递归方法如下,实际上你可以用它来做任何事情,如设置自定义字体等。。。方法如下

    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);
            }
        }
    }
    

    setContentView 在你的活动中。如果你想知道你会通过什么参数,它是 id 身份证件 到您的父容器

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

    打电话来 setupUI(findViewById(R.id.parent)) ,仅此而已。

    Activity 并将此方法放入,并使应用程序中的所有其他活动扩展此活动并调用其 setupUI() onCreate()

    希望有帮助。

    如果使用多个活动,请将公共id定义为 <RelativeLayout android:id="@+id/main_parent"> ... </RelativeLayout>

    然后扩展一个类 并定义 setupUI(findViewById(R.id.main_parent)) OnResume() 扩展这个类而不是“Activity” in your program

        2
  •  273
  •   vida    10 年前

    您可以通过执行以下步骤来实现此目的:

    1. 通过添加以下属性,使父视图(活动的内容视图)可单击且可聚焦

          android:clickable="true" 
          android:focusableInTouchMode="true" 
      
    2.     public void hideKeyboard(View view) {
              InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
              inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
          }
      
    3. 最后,设置edittext的onFocusChangeListener。

          edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
              @Override
              public void onFocusChange(View v, boolean hasFocus) {
                  if (!hasFocus) {
                      hideKeyboard(v);
                  }
              }
          });
      

    正如下面的一条评论所指出的,如果父视图是滚动视图,这可能不起作用。在这种情况下,可点击和可聚焦的InTouchMode可以直接添加到ScrollView下的视图中。

        3
  •  57
  •   Gustavo Barbosa roepit    10 年前

    这是我的解决办法。添加 OnTouchListener

    findViewById(R.id.mainLayout).setOnTouchListener(this)
    

    并将以下代码放入onTouch方法中。

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

    这样就不必遍历所有视图。

        4
  •  44
  •   sumit sonawane    6 年前

    只是在活动中重写下面的代码

     @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (getCurrentFocus() != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
        return super.dispatchTouchEvent(ev);
    }
    
        5
  •  39
  •   JJD    9 年前

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

    这里通行证 HIDE_IMPLICIT_ONLY 位于 showFlag 0 位于 hiddenFlag .

        6
  •  16
  •   Sergey Glotov Nitesh Khosla    12 年前

    好吧,我设法解决了这个问题,我在我的活动中重写了dispatchTouchEvent,在这里我使用下面的代码来隐藏键盘。

     /**
     * Called to process touch screen events. 
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
    
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                touchDownTime = SystemClock.elapsedRealtime();
                break;
    
            case MotionEvent.ACTION_UP:
                //to avoid drag events
                if (SystemClock.elapsedRealtime() - touchDownTime <= 150){  
    
                    EditText[] textFields = this.getFields();
                    if(textFields != null && textFields.length > 0){
    
                        boolean clickIsOutsideEditTexts = true;
    
                        for(EditText field : textFields){
                            if(isPointInsideView(ev.getRawX(), ev.getRawY(), field)){
                                clickIsOutsideEditTexts = false;
                                break;
                            }
                        }
    
                        if(clickIsOutsideEditTexts){
                            this.hideSoftKeyboard();
                        }               
                    } else {
                        this.hideSoftKeyboard();
                    }
                }
                break;
        }
    
        return super.dispatchTouchEvent(ev);
    }
    

    编辑:

    sFields = new EditText[] {mUserField, mPasswordField};


    这并不完美,拖动事件时间仅基于启发式,因此有时在执行长clics时不会隐藏,我还创建了一个方法来获取每个视图的所有EditText;否则,单击其他EditText时键盘将隐藏并显示。

    不过,更清洁、更短的解决方案还是受欢迎的

        7
  •  14
  •   Sergey Glotov Nitesh Khosla    14 年前

    使用 OnFocusChangeListener

    例如:

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (!hasFocus) {
                hideKeyboard();
            }
        }
    });
    

    更新 :您也可以覆盖 onTouchEvent() 在你的活动中检查触摸的坐标。如果坐标在EditText之外,则隐藏键盘。

        8
  •  13
  •   Jishi Chen    11 年前

    private EditText mEditText;
    private Rect mRect = new Rect();
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
    
        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();
    
        int x = (int) ev.getX();
        int y = (int) ev.getY();
    
        if (action == MotionEvent.ACTION_DOWN && !mRect.contains(x, y)) {
            InputMethodManager input = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            input.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
        }
        return super.dispatchTouchEvent(ev);
    }
    

    我测试过了,效果很好!

        9
  •  11
  •   0xh8h    11 年前

    重写任何活动(或扩展活动类)中的公共布尔dispatchTouchEvent(MotionEvent事件)

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        View view = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(event);
    
        if (view 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];
    
            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;
    }
    

        10
  •  11
  •   Phil    7 年前

    更多 科特林 &安培; 材料设计 使用方式 TextInputEditText EditTextView )...

    1.通过添加以下属性,使父视图(活动/片段的内容视图)可单击且可聚焦

    android:focusable="true"
    android:focusableInTouchMode="true"
    android:clickable="true"
    

    2.为所有视图创建扩展名(例如在View extension.kt文件中):

    fun View.hideKeyboard(){
        val inputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        inputMethodManager.hideSoftInputFromWindow(this.windowToken, 0)
    }
    

    class BaseTextInputEditText(context: Context?, attrs: AttributeSet?) : TextInputEditText(context, attrs){
        override fun onFocusChanged(focused: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
            super.onFocusChanged(focused, direction, previouslyFocusedRect)
            if (!focused) this.hideKeyboard()
        }
    }
    

    4.在XML中调用全新的自定义视图:

    <android.support.design.widget.TextInputLayout
            android:id="@+id/textInputLayout"
            ...>
    
            <com.your_package.BaseTextInputEditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                ... />
    
        </android.support.design.widget.TextInputLayout> 
    

    这就是全部。 无需修改控制器

        11
  •  9
  •   Fernando Camargo    12 年前

    我修改了安德烈·路易斯的解决方案,我得到了这个:

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

    但是我没有为每个视图注册一个OnTouchListener,这会带来很差的性能,而是只为根视图注册了OnTouchListener。由于事件在被使用之前一直处于气泡状态(EditText是默认使用它的视图之一),如果它到达根视图,那是因为它没有被使用,所以我关闭了软键盘。

    findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            Utils.hideSoftKeyboard(activity);
            return false;
        }
    });
    
        12
  •  8
  •   fje    12 年前

    我的所有活动都需要这种行为,所以我创建了一个类 客户活动 并“勾住”了 调度触摸事件

    1. 如果焦点不变,有人在当前输入框外轻敲,则取消输入法
    2. 如果焦点已经改变,并且下一个焦点元素不是任何类型的输入字段的实例,则关闭IME

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(ev.getAction() == MotionEvent.ACTION_UP) {
            final View view = getCurrentFocus();
    
            if(view != null) {
                final boolean consumed = super.dispatchTouchEvent(ev);
    
                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)) {
                        return consumed;
                    }
                }
                else if(viewNew instanceof EditText || viewNew instanceof CustomEditText) {
                    return consumed;
                }
    
                final InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    
                inputMethodManager.hideSoftInputFromWindow(viewNew.getWindowToken(), 0);
    
                viewNew.clearFocus();
    
                return consumed;
            }
        }       
    
        return super.dispatchTouchEvent(ev);
    }
    

    附带说明:另外,我将这些属性分配给根视图,这样就可以清除对每个输入字段的焦点,并防止输入字段在活动启动时获得焦点(使内容视图成为“焦点捕捉器”):

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        final View view = findViewById(R.id.content);
    
        view.setFocusable(true);
        view.setFocusableInTouchMode(true);
    }
    
        13
  •  6
  •   Tass    12 年前

    dispatchTouchEvent 由htafoya制造,但是:

    • 我不明白计时器部分(不知道为什么需要测量停机时间?)

    所以,我做了一个比较简单的解决方案:

    @Override
    public boolean dispatchTouchEvent(final MotionEvent ev) {
        // all touch events close the keyboard before they are processed except EditText instances.
        // if focus is an EditText we need to check, if the touchevent was inside the focus editTexts
        final View currentFocus = getCurrentFocus();
        if (!(currentFocus instanceof EditText) || !isTouchInsideView(ev, currentFocus)) {
            ((InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE))
                .hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
        return super.dispatchTouchEvent(ev);
    }
    
    /**
     * determine if the given motionevent is inside the given view.
     * 
     * @param ev
     *            the given view
     * @param currentFocus
     *            the motion event.
     * @return if the given motionevent is inside the given view
     */
    private boolean isTouchInsideView(final MotionEvent ev, final View currentFocus) {
        final int[] loc = new int[2];
        currentFocus.getLocationOnScreen(loc);
        return ev.getRawX() > loc[0] && ev.getRawY() > loc[1] && ev.getRawX() < (loc[0] + currentFocus.getWidth())
            && ev.getRawY() < (loc[1] + currentFocus.getHeight());
    }
    

    从一个 EditText 对另一个人 编辑文本 使键盘隐藏并重新显示-在我的情况下,这是需要的,因为它显示您在两个输入组件之间切换。

        14
  •  6
  •   Charles Woodson    8 年前

    我知道我没有影响力,但请认真对待我的回答。

    问题:

    解决方案: 蝴蝶刀。

    @OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }
    

    更具可读性的解决方案:

    @OnClick(R.id.activity_signup_layout) 
    public void closeKeyboard() {
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    

    说明:

    例子:

    (@OnClick(R.id.my_layout_id) 
    public void yourMethod {
        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    }
    

    Butterknife文档链接: http://jakewharton.github.io/butterknife/

    插头:

    注: 同样的结果也可以在不使用外部库Butterknife的情况下实现。只需将OnClickListener设置为父布局,如上所述。

        15
  •  4
  •   Andy Dennie    9 年前

    这里的想法是处理活动中的向下和向上操作 dispatchTouchEvent 方法。在down操作中,我们记录当前聚焦的视图(如果有的话)以及触摸是否在其中,保存这两部分信息以备以后使用。

    如果当前聚焦视图与原始聚焦视图不同 EditText ,然后我们也保持键盘打开。

    否则我们就关闭它。

    综上所述,它的工作原理如下:

    • 当触摸到当前聚焦的 ,键盘保持打开状态
    • 当从一个集中的 对另一个人 ,键盘保持打开状态(不关闭/重新打开)
    • 当接触到当前焦点之外的任何地方时 那不是另一个 编辑文本 ,键盘关闭
    • 编辑文本 要打开上下文操作栏(使用剪切/复制/粘贴按钮),键盘将保持打开状态,即使向上操作发生在焦点之外 编辑文本 编辑文本 ,不会的。
    • 当聚焦 编辑文本 位于屏幕底部,您长时间单击某个文本以选择它 保持焦点,因此键盘会像你想要的那样打开,因为我们对向下动作而不是向上动作进行“触控在视图范围内”检查。

      private View focusedViewOnActionDown;
      private boolean touchWasInsideFocusedView;
      
      
      @Override
      public boolean dispatchTouchEvent(MotionEvent ev) {
          switch (ev.getAction()) {
              case MotionEvent.ACTION_DOWN:
                  focusedViewOnActionDown = getCurrentFocus();
                  if (focusedViewOnActionDown != null) {
                      final Rect rect = new Rect();
                      final int[] coordinates = new int[2];
      
                      focusedViewOnActionDown.getLocationOnScreen(coordinates);
      
                      rect.set(coordinates[0], coordinates[1],
                              coordinates[0] + focusedViewOnActionDown.getWidth(),
                              coordinates[1] + focusedViewOnActionDown.getHeight());
      
                      final int x = (int) ev.getX();
                      final int y = (int) ev.getY();
      
                      touchWasInsideFocusedView = rect.contains(x, y);
                  }
                  break;
      
              case MotionEvent.ACTION_UP:
      
                  if (focusedViewOnActionDown != null) {
                      // dispatch to allow new view to (potentially) take focus
                      final boolean consumed = super.dispatchTouchEvent(ev);
      
                      final View currentFocus = getCurrentFocus();
      
                      // if the focus is still on the original view and the touch was inside that view,
                      // leave the keyboard open.  Otherwise, if the focus is now on another view and that view
                      // is an EditText, also leave the keyboard open.
                      if (currentFocus.equals(focusedViewOnActionDown)) {
                          if (touchWasInsideFocusedView) {
                              return consumed;
                          }
                      } else if (currentFocus instanceof EditText) {
                          return consumed;
                      }
      
                      // the touch was outside the originally focused view and not inside another EditText,
                      // so close the keyboard
                      InputMethodManager inputMethodManager =
                              (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                      inputMethodManager.hideSoftInputFromWindow(
                          focusedViewOnActionDown.getWindowToken(), 0);
                      focusedViewOnActionDown.clearFocus();
      
                      return consumed;
                  }
                  break;
          }
      
          return super.dispatchTouchEvent(ev);
      }
      
        16
  •  4
  •   swarnim dixit    8 年前

    它太简单了,只需通过以下代码将您最近的布局设置为可单击的焦点:

    android:id="@+id/loginParentLayout"
    android:clickable="true"
    android:focusableInTouchMode="true"
    

    然后为该布局编写一个方法和一个OnClickListner,这样当最上面的布局被触碰时,它将调用一个方法,在该方法中您将编写代码来关闭键盘。以下是两者的代码;

     yourLayout.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View view) {
                        hideKeyboard(view);
                    }
                });
    

    从listner调用的方法:-

     public void hideKeyboard(View view) {
         InputMethodManager imm =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    
        17
  •  4
  •   Joohay    7 年前

    对于这个简单的要求,我觉得公认的答案有点复杂。这是对我有效的,没有任何问题。

    findViewById(R.id.mainLayout).setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                return false;
            }
        });
    
        18
  •  3
  •   Alex R. R.    13 年前

        final LinearLayout llLogin = (LinearLayout)findViewById(R.id.login_fondo);
        llLogin.setOnTouchListener(
                new OnTouchListener()
                {
                    @Override
                    public boolean onTouch(View view, MotionEvent ev) {
                        InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(
                                android.content.Context.INPUT_METHOD_SERVICE);
                        imm.hideSoftInputFromWindow(mActivity.getCurrentFocus().getWindowToken(), 0);
                        return false;
                    }
                });
    
        19
  •  3
  •   lalosoft    13 年前

    显示/隐藏软键盘的方法

    InputMethodManager inputMethodManager = (InputMethodManager) currentActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (isShow) {
            if (currentActivity.getCurrentFocus() == null) {
                inputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
            } else {
                inputMethodManager.showSoftInput(currentActivity.getCurrentFocus(), InputMethodManager.SHOW_FORCED);    
            }
    
        } else {
            if (currentActivity.getCurrentFocus() == null) {
                inputMethodManager.toggleSoftInput(InputMethodManager.HIDE_NOT_ALWAYS, 0);
            } else {
                inputMethodManager.hideSoftInputFromInputMethod(currentActivity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);    
            }
    
        }
    

    我希望他们有用

        20
  •  3
  •   Sai    6 年前

    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)
    }
    
        21
  •  2
  •   Uzair    9 年前

    我已经改进了这个方法,将下面的代码放在一些UI实用程序类中(最好,不一定),这样就可以从所有活动或片段类中访问它来实现它的目的。

    public static void serachAndHideSoftKeybordFromView(View view, final Activity act) {
        if(!(view instanceof EditText)) {
            view.setOnTouchListener(new View.OnTouchListener() {
                public boolean onTouch(View v, MotionEvent event) {
                    hideSoftKeyboard(act);
                    return false;
                }
            });
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                View nextViewInHierarchy = ((ViewGroup) view).getChildAt(i);
                serachAndHideSoftKeybordFromView(nextViewInHierarchy, act);
            }
        }
    }
    public static void hideSoftKeyboard (Activity activity) {
        InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
    }
    

    然后举例来说,你需要从活动中调用它,如下所示调用它;

    UIutils.serachAndHideSoftKeybordFromView(findViewById(android.R.id.content), YourActivityName.this);
    

    findViewById(android.R.id.content)

    这将为我们提供当前组的根视图(您不能在根视图上设置id)。

    干杯:)

        22
  •  2
  •   JJD    9 年前

    尝试将stateHidden设置为您的活动 windowSoftInputMode 价值

    http://developer.android.com/reference/android/R.attr.html#windowSoftInputMode

    this.getWindow().setSoftInputMode(
        WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
    
        23
  •  2
  •   Jean-François Corbett    7 年前

    活动

     @Override
     public boolean dispatchTouchEvent(MotionEvent ev) {
         ScreenUtils.hideKeyboard(this, findViewById(android.R.id.content).getWindowToken());
         return super.dispatchTouchEvent(ev);
     }
    

    屏蔽

     public static void hideKeyboard(Context context, IBinder windowToken) {
         InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
         imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS);
     }
    
        24
  •  2
  •   Haseeb Javed    7 年前

    只需在类中添加此代码 @过边

    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);
    }
    
        25
  •  1
  •   AndyMc    12 年前

            findViewById(android.R.id.content).setOnTouchListener(new OnTouchListener() {           
            public boolean onTouch(View v, MotionEvent event) {
                Utils.hideSoftKeyboard(v);
                return false;
            }
        });
    

    在一个单独的Utils类中是。。。

        public static void hideSoftKeyboard(View v) {
        InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
    
        26
  •  1
  •   ralphgabb    10 年前

    这可能很旧,但我是通过一个自定义类来实现的

    public class DismissKeyboardListener implements OnClickListener {
    
        Activity mAct;
    
        public DismissKeyboardListener(Activity act) {
            this.mAct = act;
        }
    
        @Override
        public void onClick(View v) {
            if ( v instanceof ViewGroup ) {
                hideSoftKeyboard( this.mAct );
            }
        }       
    }
    
    public void hideSoftKeyboard(Activity activity) {
            InputMethodManager imm = (InputMethodManager)
            getSystemService(Activity.INPUT_METHOD_SERVICE);
            imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }
    

    ****注意,只有主容器应该实现这个类(用于优化)****

    并按如下方式实施:

    Parent.setOnClickListener( new DismissKeyboardListener(this) ); 
    

    ---竖起大拇指如果它能帮助你。。。 ---干杯拉尔夫---

        27
  •  1
  •   Cadmonkey33    10 年前

    这是fje答案的一个稍加修改的版本,它基本上工作得很好。

    此版本使用ACTION_DOWN,因此执行滚动操作也会关闭键盘。

    @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);
    }
    
        28
  •  1
  •   Hiren Patel    9 年前

    我是这样做的:

    @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())
                    hideKeyboard(this);
            }
        return super.dispatchTouchEvent(ev);
    }
    

    隐藏键盘代码 :

    public static void hideKeyboard(Activity act) {
        if(act!=null)
          ((InputMethodManager)act.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((act.getWindow().getDecorView().getApplicationWindowToken()), 0);
      }
    

    多恩

        29
  •  1
  •   Sudhanshu Gaur    9 年前

    要解决这个问题,首先要使用Edittext的setOnFocusChangeListener

    edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    if (!hasFocus) {
                        Log.d("focus", "focus loosed");
                        // Do whatever you want here
                    } else {
                        Log.d("focus", "focused");
                    }
                }
            });
    

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if ( v instanceof EditText) {
                Rect outRect = new Rect();
                v.getGlobalVisibleRect(outRect);
                if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
                    Log.d("focus", "touchevent");
                    v.clearFocus();
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
        }
        return super.dispatchTouchEvent(event);
    }
    

    现在,当用户单击外部时,首先将调用dispatchTouchEvent,然后将清除编辑文本中的焦点。现在,将调用OnFocusChangeListener,焦点已更改。现在,您可以做任何您想做的事情,希望它起作用

        30
  •  1
  •   Jeffy    8 年前
    @Override
        public boolean onTouchEvent(MotionEvent event) {
            InputMethodManager imm = (InputMethodManager)getSystemService(Context.
                    INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            return true;
        }