Intereting Posts
Остаток логотипа панели действий оставлен Java, специальный сортировка ArrayList с более длинными записями в конце Переход с флип-карты между двумя действиями Android Android Java – String .replaceAll для замены определенных символов (регулярное выражение) Лучший способ получить бесплатную версию Android-приложения Android WebView.postUrl () показывает пустой экран при отправке на HTTPS-URL Переход общего элемента Android между фрагментами, имеющими представление recyclerview & details Как скомпилировать статическую библиотеку с помощью Android NDK? Заголовок списка Android Интерстициальное объявление показывается черным (->) AFMA_ReceiveMessage не определен (: 1) Где я могу найти исходный код Java для шифрования Vigenere? Intent.getAction () бросает Null + Android Медленный переход активности: множественное «инициализирующее состояние раздувания» в LogCat Как запретить экрану устройства Android отключиться во время выполнения Activity? Как поддерживать состояние ViewPager в ListView?

Кнопка перехвата назад с мягкой клавиатуры

У меня есть активность с несколькими полями ввода. При запуске активности отображается мягкая клавиатура. Когда кнопка «назад» нажата, мягкая клавиатура закрывается и для закрытия активности мне нужно снова нажать кнопку «Назад».

Поэтому вопрос: можно ли перехватить кнопку «Назад», чтобы закрыть мягкую клавиатуру и завершить InputMethodService одним нажатием кнопки «Назад» без создания пользовательского InputMethodService ?

PS Я знаю, как перехватить кнопку «Назад» в других случаях: onKeyDown() или onBackPressed() но в этом случае это не работает: только второе нажатие кнопки «Назад» перехвачено.

Solutions Collecting From Web of "Кнопка перехвата назад с мягкой клавиатуры"

Да, вполне возможно показать и скрыть клавиатуру и перехватить вызовы на кнопку «Назад». Это немного дополнительные усилия, поскольку было упомянуто, что нет прямого способа сделать это в API. Ключ состоит в том, чтобы переопределить boolean dispatchKeyEventPreIme(KeyEvent) в макете. Мы создаем наш макет. Я выбрал RelativeLayout, поскольку он был базой моей деятельности.

 <?xml version="1.0" encoding="utf-8"?> <com.michaelhradek.superapp.utilities.SearchLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.michaelhradek.superapp" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@color/white"> 

Внутри нашей деятельности мы настраиваем наши поля ввода и вызываем setActivity(...) .

 private void initInputField() { mInputField = (EditText) findViewById(R.id.searchInput); InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY); mInputField.setOnEditorActionListener(new OnEditorActionListener() { @Override public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_SEARCH) { performSearch(); return true; } return false; } }); // Let the layout know we are going to be overriding the back button SearchLayout.setSearchActivity(this); } 

Очевидно, что initInputField() устанавливает поле ввода. Он также позволяет клавишам ввода выполнять функциональные возможности (в моем случае поиск).

 @Override public void onBackPressed() { // It's expensive, if running turn it off. DataHelper.cancelSearch(); hideKeyboard(); super.onBackPressed(); } 

Поэтому, когда onBackPressed() вызывается в нашем макете, мы можем делать все, что захотим, чтобы скрыть клавиатуру:

 private void hideKeyboard() { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(mInputField.getWindowToken(), 0); } 

Во всяком случае, вот моя переоценка RelativeLayout.

 package com.michaelhradek.superapp.utilities; import android.app.Activity; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.widget.RelativeLayout; /** * The root element in the search bar layout. This is a custom view just to * override the handling of the back button. * */ public class SearchLayout extends RelativeLayout { private static final String TAG = "SearchLayout"; private static Activity mSearchActivity;; public SearchLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SearchLayout(Context context) { super(context); } public static void setSearchActivity(Activity searchActivity) { mSearchActivity = searchActivity; } /** * Overrides the handling of the back key to move back to the * previous sources or dismiss the search dialog, instead of * dismissing the input method. */ @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { Log.d(TAG, "dispatchKeyEventPreIme(" + event + ")"); if (mSearchActivity != null && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { KeyEvent.DispatcherState state = getKeyDispatcherState(); if (state != null) { if (event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { state.startTracking(event, this); return true; } else if (event.getAction() == KeyEvent.ACTION_UP && !event.isCanceled() && state.isTracking(event)) { mSearchActivity.onBackPressed(); return true; } } } return super.dispatchKeyEventPreIme(event); } } 

К сожалению, я не могу взять кредит. Если вы проверите источник Android для быстрого окна SearchDialog, вы увидите, откуда взялась эта идея.

OnKeyDown () и onBackPressed () не работает для этого случая. Вы должны использовать onKeyPreIme .

Первоначально вы должны создать собственный текст редактирования, который расширяет EditText. И тогда вы должны реализовать метод onKeyPreIme, который управляет KeyEvent.KEYCODE_BACK . После этого один назад достаточно, чтобы решить вашу проблему. Это решение работает для меня отлично.

CustomEditText.java

 public class CustomEditText extends EditText { Context context; public CustomEditText(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } @Override public boolean onKeyPreIme(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // User has pressed Back key. So hide the keyboard InputMethodManager mgr = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); mgr.hideSoftInputFromWindow(this.getWindowToken(), 0); // TODO: Hide your view as you do it in your activity } return false; } 

В вашем XML

 <com.YOURAPP.CustomEditText android:id="@+id/CEditText" android:layout_height="wrap_content" android:layout_width="match_parent"/> 

В вашей деятельности

 public class MainActivity extends Activity { private CustomEditText editText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); editText = (CustomEditText) findViewById(R.id.CEditText); } } 

Я узнал, что переопределение метода dispatchKeyEventPreIme класса макета также хорошо работает. Просто установите основную активность как атрибут и запустите предопределенный метод.

 public class LinearLayoutGradient extends LinearLayout { MainActivity a; public void setMainActivity(MainActivity a) { this.a = a; } @Override public boolean dispatchKeyEventPreIme(KeyEvent event) { if (a != null) { InputMethodManager imm = (InputMethodManager) a .getSystemService(Context.INPUT_METHOD_SERVICE); if (imm.isActive() && event.getKeyCode() == KeyEvent.KEYCODE_BACK) { a.launchMethod; } } return super.dispatchKeyEventPreIme(event); } } 

У меня был успех, переопределив dispatchKeyEvent :

 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { finish(); return true; } return super.dispatchKeyEvent(event); } 

Он скрывает клавиатуру и завершает работу.

Как вы показываете мягкую клавиатуру?

Если вы используете InputMethodManager.showSoftInput() , вы можете попробовать перейти в ResultReceiver и реализовать onReceiveResult() для обработки RESULT_HIDDEN

http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html

У меня была такая же проблема, но обойти ее, перехватив нажатие клавиши. В моем случае (HTC Desire, Android 2.2, Application API Level 4) он закрывает клавиатуру и сразу же завершает работу. Не знаю, почему это тоже не должно работать для вас:

 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { onBackPressed(); return true; } return super.onKeyUp(keyCode, event); } /** * Called when the activity has detected the user's press of the back key */ private void onBackPressed() { Log.e(TAG, "back pressed"); finish(); } 

Используйте onKeyPreIme(int keyCode, KeyEvent event) и проверьте событие KeyEvent.KEYCODE_BACK . Это очень просто, без каких-либо причудливых кодировок.

Попробуйте этот код в вашей реализации BackPressed ( кнопка «Back Back» в android ):

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

Я предлагаю вам посмотреть @ Закрыть / скрыть Android Soft Keyboard