2011-07-13 139 views
32

我只想在点击“edittext”之外时自动失去焦点并隐藏键盘。目前,如果我点击“edittext”,它将重点关注,但我需要点击后退按钮才能确定焦点。点击外部edittext以失去焦点

+0

相关问题:http://stackoverflow.com/q/4165414/782870。我认为大部分答案已经过测试,并且已经发现有效。 – vida

+0

我找到了这个答案:http://stackoverflow.com/a/28939113/2610855最好的一个。 – Loenix

回答

15

假设您的EditText放置在线性布局或其他ViewGroup上。然后你应该让这个容器可点击,可聚焦和focusableInTouchMode。该组onClickListener到这个容器用的onClick覆盖方法下面的代码后:

@Override 
public void onClick(View view) { 
    InputMethodManager imm = (InputMethodManager) view.getContext() 
      .getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
} 
+1

就我而言,我在文本字段的焦点上显示数字键盘。我试图使用你的解决方案。当我点击背景视图时,数字键盘转换成AlphaNumeric键盘,然后当我再次点击时,它会消失。 –

13

@woodshy有隐藏键盘,但也许将代码中onClick答案是不是把它在onFocusChanged好。至于迫使它失去焦点,您需要设置对象要转移焦点,在其XML文件:

android:focusable="true" 
android:focusableInTouchMode ="true" 
+0

我可以有一个与此相关的问题:你的意思是说这些代码应该放在LinearLayout中,或者是我想要忽略的EditText?谢谢。 – detno29

+0

你应该把它作为父视图的属性(你的活动的内容视图)。你可能想看看这个:http://stackoverflow.com/a/19828165/782870 – vida

-5

我有同样的要求,因为我不得不隐藏键盘当我触摸任何地方我的EditText框外。 setOnFocusChangeListener不会执行此任务,即使您在编辑文本框之外触摸仍处于选中状态。

为此,我使用了解决方案edc598 here

  • 我首先得到了包含整个视图的MainLayout,并添加了触摸监听器。
  • 当onTouch事件被触发时,我检查EditText框是否有焦点。
  • 如果EditText框有焦点,我检查事件的X-Y坐标。
  • 根据我的EditText框的位置我隐藏键盘,如果箱子从here修改

代码示例外触及的任何地方:

LinearLayout MainLayout = (LinearLayout) findViewById(R.id.MainLayout); 
EditText textBox  = (EditText) findViewById(R.id.textBox); 
int X_TOP_LEFT  = 157; 
int Y_TOP_LEFT  = 388; 
int X_BOTTOM_RIGHT = 473; 
int Y_BOTTOM_RIGHT = 570; 
MainLayout.setOnTouchListener(new View.OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // TODO Auto-generated method stub 
     if(textBox.isFocused()){ 

      Log.i("Focussed", "--" + event.getX() + " : " + event.getY() + "--"); 

      if(event.getX() <= 157 || event.getY() <= 388 || event.getX() >= 473 || event.getY() >= 569){ 
       //Will only enter this if the EditText already has focus 
       //And if a touch event happens outside of the EditText 
       textBox.clearFocus(); 
       InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(v.getWindowToken(), 0); 
       //Do something else 
      } 
     } 
     Log.i("X-Y coordinate", "--" + event.getX() + " : " + event.getY() + "--"); 
    //Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); 
     return false; 
    } 
}); 
+32

老兄,你得开玩笑我们这个神奇的数字...... –

+0

绝对不需要边界检查,因为EditText会吃触摸事件。 – pstoppani

1

所以我搜索周围一点点,和没有其他解决方案是我正在寻找的。在我看来,焦点在EditText视图上表现得很奇怪。

我所做的是什么...

  1. 确保根视图是一个RelativeLayout的

  2. 添加覆盖布局已经结束,这将使键盘disapear面积,但不EditText上。类似下面:

在我的情况下,是的EditText在容器在屏幕的底部。所以它涵盖了其他所有。

  • 具有看起来有点像这样的一个方法:
  •  
        private void hideKeyboard() { 
         final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
         imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 
         keyboardOverlay.setVisibility(View.GONE); 
         editText.clearFocus(); 
        } 
    
  • 现在请的onClick此方法您创建的叠加层。

  • 我们现在想要的是在按editText时使覆盖层可见。你不能使用onFocus事件(至少我没有得到它的工作......)所以我做的是我管理的onTouch事件。

  •  
    editText.setOnTouchListener(new OnTouchListener() { 
    
        @Override 
        public boolean onTouch(final View v, final MotionEvent event) { 
         keyboardOverlay.setVisibility(View.VISIBLE); 
         editText.requestFocus(); 
         return false; 
        } 
    }); 
    

    的requestFocus()方法在这里是不覆盖与onTouch的焦点事件。

    快速建议,当您尝试此操作时,您可以向叠加层添加背景颜色以查看究竟发生了什么。

    希望它适合你!

    +0

    有没有更好的方法来做到这一点? – Gohan

    11

    为了解决这个问题,你必须做的是,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"); 
           } 
          } 
         }); 
    

    ,然后你需要做的是覆盖dispatchTouchEvent其中包含EDITTEXT看到下面的代码的活动是什么

    @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将被调用,然后将清除焦点从editext现在你的OnFocusChangeListener将被调用焦点已被改变,现在他你可以做任何你想做的事情,希望它能起作用:)

    +0

    我喜欢这种方法。此外,在editText的直接父级的布局中添加 'android:focusable =“true”'和'android:focusableInTouchMode =“true”''。 –

    +0

    '重点疏散'应该'重点丢失':) :)) – Stack

    0

    下面的代码对我来说很完美,我经常使用这个代码关闭EditText以外的任何地方的SoftKeyboard onTouch

    public void hideSoftKeyboard() 
    { 
         //Hides the SoftKeyboard 
         InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE); 
         inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0); 
    } 
    
    public void setupUI(View view) 
    { 
         String s = "inside"; 
         //Set up touch listener for non-text box views to hide keyboard. 
         if (!(view instanceof EditText)) { 
    
          view.setOnTouchListener(new View.OnTouchListener() { 
    
           public boolean onTouch(View v, MotionEvent event) { 
            hideSoftKeyboard(); 
            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); 
          } 
         }  
    } 
    

    所以,你只需要在你的onCreate()方法和voilla调用一次setupUI()功能,您hidingSoftKeyboard是设置!

    对于失去EditText的完整焦点,只需在您的hideSoftKeyboard()函数中执行editText.clearFocus()即可。

    0

    您可以通过执行以下步骤实现:

    词根记忆父视图(你的活动内容视图),点击和可聚焦通过添加以下属性

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

    2.Implement一hideKeyboard()方法

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