我只想在“edittext”外单击时自动失去焦点并隐藏键盘。目前,如果我点击“edittext”它会聚焦,但我需要点击后退按钮来取消聚焦。
答案 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视图上表现得很奇怪。
我做的是......
确保根视图是RelativeLayout
添加覆盖布局,该布局超出了使键盘消失的区域,但不包括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覆盖焦点事件。
快速建议,当您尝试此操作时,您可以为叠加层添加背景颜色,以准确查看正在发生的事情。
希望它适合你!
答案 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。
从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;
}
});