点击外部edittext以失去焦点

时间:2011-07-13 11:13:07

标签: android focus android-edittext

我只想在“edittext”外单击时自动失去焦点并隐藏键盘。目前,如果我点击“edittext”它会聚焦,但我需要点击后退按钮来取消聚焦。

9 个答案:

答案 0 :(得分:19)

要解决此问题,您需要做的是首先使用该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");
                }
            }
        });

然后您需要做的是覆盖包含该Edittext的活动中的dispatchTouchEvent,参见下面的代码

@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将被调用焦点已被更改,现在在这里你可以做任何你做的事情想做,希望它有效:)

答案 1 :(得分:18)

@woodshy有隐藏键盘的答案,但是将代码放在onClick中可能不如将它放在onFocusChanged中。至于强制它失去焦点,你需要在XML文件中设置你想要将焦点转移到的对象:

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

答案 2 :(得分:14)

假设您的EditText放置在Linear布局或其他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);
}

答案 3 :(得分:1)

所以我搜索了一下,没有其他解决方案正是我想要的。在我看来,焦点在EditText视图上表现得很奇怪。

我做的是......

  1. 确保根视图是RelativeLayout

  2. 添加覆盖布局,该布局超出了使键盘消失的区域,但不包括EditText。如下所示:

  3. 就我而言,EditText位于屏幕底部的容器中。所以它涵盖了其他每一个。

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

      2. 我们现在想要的是在按下editText时使叠加层可见。你不能使用onFocus事件(至少我没有让它工作......)所以我做的是我管理了onTouch事件。

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

        这里的requestFocus()不会使用onTouch覆盖焦点事件。

        快速建议,当您尝试此操作时,您可以为叠加层添加背景颜色,以准确查看正在发生的事情。

        希望它适合你!

答案 4 :(得分:1)

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

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

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

2.实现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);
            }
        }
    });

答案 5 :(得分: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);
            }
        }    
}

所以你只需要在setupUI()方法中调用一次onCreate()函数,然后设置hiddenSoftKeyboard!

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

答案 6 :(得分:0)

在按钮或任何视图中设置:this.getCurrentFocus()。clearFocus(); 例如:

@Override
public boolean onMenuOpened(int featureId, Menu menu) {
    InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
    this.getCurrentFocus().clearFocus();
    return super.onMenuOpened(featureId, menu);
}

答案 7 :(得分:0)

这是所有屏幕的通用方法。参加活动

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
    clearFocusOnOutsideClick()
    return super.dispatchTouchEvent(ev)
}
/*
* Clear focus on outside click
* */
private fun clearFocusOnOutsideClick() {
    currentFocus?.apply {
        if (this is EditText) {
            clearFocus()
        }
        //Hide keyboard
        val imm: InputMethodManager =
            getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
    }
}

答案 8 :(得分:-7)

当我触摸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;
    }
});