Скрыть мягкую клавиатуру при потере фокуса
Когда у нас есть EditText
, и он теряет фокус (для элемента, который не нуждается в клавиатуре), должна ли мягкая клавиатура спрятаться автоматически или мы должны скрыть ее сами?
Я перемещаю фокус с AutoCompleteSearchView
(который должен вести себя как EditText
, как я полагаю) к Button
, requestFocus()
возвращает true, но клавиатура не скрывает.
Ответы
Ответ 1
Лучший способ - установить OnFocusChangeListener для EditText, а затем добавить код на клавиатуре в метод OnFocusChange слушателя. Android автоматически закроет клавиатуру, когда EditText потеряет фокус.
Что-то вроде этого в методе OnCreate:
EditText editText = (EditText) findViewById(R.id.textbox);
OnFocusChangeListener ofcListener = new MyFocusChangeListener();
editText.setOnFocusChangeListener(ofcListener);
а затем добавьте класс:
private class MyFocusChangeListener implements OnFocusChangeListener {
public void onFocusChange(View v, boolean hasFocus){
if(v.getId() == R.id.textbox && !hasFocus) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
Ответ 2
Попробуйте это
/**
* Hide keyboard on touch of UI
*/
public void hideKeyboard(View view) {
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
hideKeyboard(innerView);
}
}
if (!(view instanceof EditText)) {
view.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(v);
return false;
}
});
}
}
/**
* Hide keyboard while focus is moved
*/
public void hideSoftKeyboard(View view) {
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) contentsContext_
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (inputManager != null) {
if (android.os.Build.VERSION.SDK_INT < 11) {
inputManager.hideSoftInputFromWindow(view.getWindowToken(),
0);
} else {
if (this.getCurrentFocus() != null) {
inputManager.hideSoftInputFromWindow(this
.getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
}
view.clearFocus();
}
view.clearFocus();
}
}
}
Ответ 3
Android не скроет вам клавиатуру. Если вы хотите, чтобы клавиатура скрывалась, когда ваш EditText
теряет фокус, попробуйте использовать такой метод в этом случае:
private void hideKeypad() {
EditText edtView = (EditText) findViewById(R.id.e_id);
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(edtView.getWindowToken(), 0);
}
Ответ 4
Попробуйте это, возможно, это решит вашу проблему.
private void hideKeyboard() {
InputMethodManager mImMan = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
mImMan.hideSoftInputFromWindow(mYourEdttxtName.getWindowToken(), 0);
}
Вы можете найти более подробную информацию из здесь.
Ответ 5
Просто создайте один статический метод
public static void touchScreenAndHideKeyboardOnFocus(View view, final Activity activity) {
if (view instanceof EditText) {
view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
if(activity != null) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
if (activity.getCurrentFocus() != null) {
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
}
}
});
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
touchScreenAndHideKeyboardOnFocus(innerView, activity);
}
}
}
view - это корневой вид вашего макета.. но будьте осторожны, если в вашем редакторе есть еще один прослушиватель фокуса.
Ответ 6
Вы можете переопределить метод dispatchTouchEvent
для его достижения:
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
/**
* It gets into the above IF-BLOCK if anywhere the screen is touched.
*/
View v = getCurrentFocus();
if ( v instanceof EditText) {
/**
* Now, it gets into the above IF-BLOCK if an EditText is already in focus, and you tap somewhere else
* to take the focus away from that particular EditText. It could have 2 cases after tapping:
* 1. No EditText has focus
* 2. Focus is just shifted to the other EditText
*/
Rect outRect = new Rect();
v.getGlobalVisibleRect(outRect);
if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) {
v.clearFocus();
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
}
return super.dispatchTouchEvent( event );
}
Бонус: В случае улучшения фокусировки EditText, порядок срабатывания события:
-
onFocusChange()
другого EditText вызывается (если другой edittext теряет фокус)
-
ACTION_DOWN
называется
- Наконец, метод
onFocusChange()
этого EditText будет вызван.
Ответ 7
моя проблема решена с помощью этого кода (в фрагменте)
LinearLayout linearLayoutApply=(LinearLayout)rootView.findViewById(id.LinearLayoutApply);
linearLayoutApply.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus)
{
hideKeyBoard(v);
}
}
});
hideKeyBoard
public void hideKeyBoard(View v)
{
InputMethodManager imm=(InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
Ответ 8
Решение этой проблемы уже найдено здесь.
Он использует DispatchTouchEvent для активности и не привязывает каждый EditText к событию FocusChange или Touch.
Это гораздо лучшее решение.
Моя реализация Xamarin выглядит следующим образом:
public override bool DispatchTouchEvent(MotionEvent ev)
{
if (ev.Action == MotionEventActions.Down)
{
var text = CurrentFocus as EditText;
if (text != null)
{
var outRect = new Rect();
text.GetGlobalVisibleRect(outRect);
if (outRect.Contains((int) ev.RawX, (int) ev.RawY)) return base.DispatchTouchEvent(ev);
text.ClearFocus();
HideSoftKeyboard();
}
}
return base.DispatchTouchEvent(ev);
}
protected void HideSoftKeyboard()
{
var inputMethodManager = (InputMethodManager) GetSystemService(InputMethodService);
inputMethodManager.HideSoftInputFromWindow(CurrentFocus.WindowToken, 0);
}