Питання Закрити / сховати програмну клавіатуру Android


У мене є EditText і a Button у моєму макеті

Після написання в полі редагування та натискання на Button, Я хочу приховати віртуальну клавіатуру. Я припускаю, що це простий шматочок коду, але де я можу знайти приклад цього?


3093


походження


Що робити, якщо у вас є лише один EditText і кілька кнопок, як прапорці та радіоприймачі? Єдине місце, де вам потрібна клавіатура, знаходиться в єдиному EditText. Як ви зареєструєтеся, щоб дізнатись, що для приховання клавіатури вибрано / натиснуто ще щось інше? - AlikElzin-kilaka
я відчуваю дурість. Я не можу приховати клавіатуру в ICS. Випробували всі методи тут і їх комбінації. У жодному разі. Метод показує, що він працює, але я не можу приховати це, незалежно від того, який вітерний токен, сховати прапори, маніфест налаштування або свічки для будь-яких святих. На дисплеї клавіатури я завжди бачу це: I / LatinIME (396): InputType.TYPE_NULL вказано W / LatinIME (396): Неочікуваний вхідний клас: inputType = 0x00000000 imeOptions = 0x00000000 - rupps
/ ** * Цей метод використовується для приховування м'якої клавіатури. * @param activity * / public void hideSoftKeyboard (Activity activity) {InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService (Activity.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow (activity.getCurrentFocus (). getWindowToken (), 0); } - Harshal Benake
Дуже сумно, що таке, здавалося б, просте питання настільки популярне. - lang2
Так, вірно, як Android, є одно- та дворядні рішення для простих речей. - milosmns


Відповіді:


Щоб прояснити це безглуздя, я хотів би почати, вибачившись від імені всіх користувачів Android, щоб Google справді смішно поводився з м'якою клавіатурою. Причиною є так багато відповідей, кожен по-різному, бо таке ж просте запитання викликає те, що цей API, як і багато хто інші на Android, жахливо розроблений. Я не можу придумати ніякого ввічливого способу заявити це.

Я хочу приховати клавіатуру. Я очікую надати Android такий вираз: Keyboard.hide(). Кінець. Велике спасибі. Проте Android має проблему. Ви повинні використовувати InputMethodManager сховати клавіатуру. Гаразд, добре, це API Android на клавіатурі. БЕЗ! Ви повинні мати Context щоб отримати доступ до ІММ. Тепер у нас є проблема. Я, можливо, захочу сховати клавіатуру від статичного або класу служб, який не використовується або не потрібний для будь-якого Context. І ще гірше, IMM вимагає, щоб ви вказали що View (або ще гірше, що Window) Ви хочете сховати клавіатуру FROM.

Це робить приховування клавіатури настільки складною. Шановний Google: Коли я шукаю рецепт торт, то немає RecipeProvider на Землі, яка відмовляється надавати мені рецепт, якщо я спочатку не відповім, до кого буде з'їдено торт, і де він буде з'ївся !!

Ця сумна історія закінчується потворною істиною: щоб сховати клавіатуру Android, вам потрібно буде надати 2 форми ідентифікації: a Context і або а View або a Window.

Я створив статичний метод утиліт, який може виконувати роботу ДУЖЕ твердо, якщо ви називаєте це з Activity.

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Майте на увазі, що цей утиліт метод ТІЛЬКИ працює, коли викликається з Activity! Вищевказаний метод викликає getCurrentFocus від цілі Activity щоб отримати відповідний токен вікна.

Але припустимо, ви хочете приховати клавіатуру від EditText розміщений в DialogFragment? Ви не можете використовувати вказаний вище метод:

hideKeyboard(getActivity()); //won't work

Це не спрацює, оскільки ви передасте посилання на Fragmentросійський хост Activity, який не буде мати фокусного контролю в той час як Fragment показано! Оце Так! Отже, для того, щоб приховати клавіатуру від фрагментів, я вдаюся до нижчого рівня, більш поширеного і потворного:

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Нижче наведено додаткову інформацію, яка збирається, оскільки більше часу витрачається на переслідування цього рішення:

Про windowSoftInputMode

Існує ще одна точка розмови, про яку слід знати. За умовчанням Android автоматично призначає перший фокус EditText або фокусується контроль у вашому Activity. Зрозуміло, що InputMethod (зазвичай, м'яка клавіатура) реагує на події фокусу, показуючи себе. The windowSoftInputMode атрибут в AndroidManifest.xml, коли встановлено на stateAlwaysHidden, наказує клавіатурі ігнорувати цей автоматично призначений початковий фокус.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

Майже неймовірно, здається, що нічого не роблять, щоб не відкрити клавіатуру, коли ви торкаєтеся елемента керування (крім focusable="false" і / або focusableInTouchMode="false" призначені для контролю). Очевидно, що параметр windowSoftInputMode застосовується лише до автоматичних фокусних подій, а не для фокусування подій, викликаних з-за дотику.

Тому stateAlwaysHidden ДУЖЕ погано називається справді. Ймовірно, це слід назвати ignoreInitialFocus замість цього.

Сподіваюся, це допоможе.


UPDATE: Більше способів отримати токен вікна

Якщо немає зосередженого вигляду (наприклад, може статися, якщо ви просто змінили фрагменти), є й інші представлення, які нададуть корисний токен вікна.

Це альтернативи вищезазначеному коду if (view == null) view = new View(activity);  Вони прямо не стосуються вашої діяльності.

Всередині класу фрагмента:

view = getView().getRootView().getWindowToken();

Даний фрагмент fragment як параметр:

view = fragment.getView().getRootView().getWindowToken();

Починаючи з вашого вмісту:

view = findViewById(android.R.id.content).getRootView().getWindowToken();

UPDATE 2: очистити фокус, щоб не показувати клавіатуру ще раз, якщо ви відкриваєте програму з фону

Додайте цей рядок до кінця методу:

view.clearFocus();


1024



Я не думаю, що ви повинні змінювати softInputMode. Це перевизначить налаштування AndroidManifest. - Kyle Ivey
Велике спасибі за ретельну відповідь. Достатній смак для того, щоб початківець міг добре розуміти м'яку клавіатуру. Я хотів сховати / показати клавіатуру з фрагмента, і це була найбільш прийнятна відповідь, яку я знайшов. - Tina
Добрий і корисний відповідь. Це було одне з тих надзвичайно рідких повідомлень на StackOverflow, які було приємно читати. - Rameez Hussain
@AlexanderFarber так, зазвичай а EditText, але я вважаю, що все видиме View буде працювати (наприклад, TextView), оскільки View використовується лише для отримання токену вікна (це те, що приховати від клавіатури). Крім того, я вважаю, що View повинен приймати від господаря Activity а не Fragment - rmirabelle
@rmirabelle в a Fragment Здається, що ви можете використовувати getActivity().getWindow().getDecorView() - McX


Ви можете змусити Android, щоб приховати віртуальну клавіатуру за допомогою InputMethodManager, зателефонувавши hideSoftInputFromWindow, що пройшов у токені вікна, що містять ваш фокус.

// Check if no view has focus:
View view = this.getCurrentFocus();
if (view != null) {  
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

Це змусить клавіатуру бути прихованою у всіх ситуаціях. У деяких випадках ви захочете перейти InputMethodManager.HIDE_IMPLICIT_ONLY як другий параметр, який забезпечує лише приховування клавіатури, коли користувач не явно заставляє його з'являтись (утримуючи меню).

Примітка: Якщо ви хочете зробити це в Котліні, використовуйте: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


4176



Завдяки цьому, здається, це чудово працює, якщо використовувати 0 як другий параметр. Але якщо я використовую InputMethodManager.HIDE_IMPLICIT_ONLY, клавіатура ніколи не прихована (хоча я не тримаю вниз меню). Будь-які натяки? - RoflcoptrException
Прохолодно Просто щоб прояснити, це лише відхиляє його, якщо є, але не буде запобігти це з з'являється, вірно? - Cheezmeister
Можливо, буде корисно називати editText.clearFocus (), перш ніж приховувати softInput - user2224350
Дзвінок editText.clearFocus() потім InputMethodManager.HIDE_IMPLICIT_ONLY навіть працює 4.1 - sprocket12
Що працював для мене на 4.4 / htc виконував View focused = getCurrentFocus() щоб отримати те, що є безумовно в даний час цілеспрямований перегляд, дзвінок focused.clearFocus(), і потім inputMethodManager.hideSoftInputFromWindow(focused.getWindowToken(), 0) (з чіткими прапорами). - Ionoclast Brigham


Також корисно для приховування клавіатури:

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

Це можна використовувати для придушення м'якої клавіатури, доки користувач не торкнеться режиму редагування тексту.


742



Ви також можете досягти такого ж ефекту, додаючи android: windowSoftInputMode = "stateHidden" на вашу активність у маніфесті. - BoD
Спробував це в фрагменті (посилання на власну активність) на рівні API 9, і це, на жаль, не спрацювало. Випробували зателефонувати на onResume і onActivityCreated - ніякого ефекту. - AgentKnopf
Я працюю в діалоговому вікні, і це працювало. Я використовую Android 3.2. Я поклав його в метод onCreateDialog (Bundle). Він не працював у методі onCreate. Діалогове вікно = super.onCreateDialog (savedInstanceState); dialog.getWindow (). setSoftInputMode (WindowManager.LayoutParams SOFT_INPUT_STATE_ALWAYS_HIDDEN); Результат полягає в тому, що мій погляд з EditTexts у ньому відображається без клавіатури. Коли користувач торкається редагованого тексту, відображається клавіатура. - flobacca
Це не спрацьовує, коли фокус залишається в EditText (наприклад, після натискання кнопки). Використовуйте рішення Reto для цього. - Noumenon
Чому перш за все маніфест налаштування - погана ідея? Я називаю це фрагментом. Немає налаштувань маніфесту, що застосовується до фрагмента ... - Greg Ennis


Я отримав ще одне рішення, щоб сховати клавіатуру:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

Тут пройти HIDE_IMPLICIT_ONLY на позиції showFlag і 0 на позиції hiddenFlag. Він насильно закриє м'яку клавіатуру.


294



Ви використовуєте прапорець hide у параметрі showflags. Це працює тільки тому, що константи використовують однакові цілі числа. Приклад використання правильних прапорів - Alex
протестований на Android 4.0, мені подобається це рішення, тому що у мене є кілька текстів редагування, кнопок цієї діяльності, які можуть фокусуватися
Чому це показує клавіатуру, якщо вона була прихована? :)
@ Марк: Оскільки метод називається "toggleSoftInput", а не "hideSoftInput" :) - Sver
Це рішення показує клавіатуру, якщо вона прихована. Це не правильно - Michael Katkov


Рішення Майєра працює і для мене. У моєму випадку найвищий рівень мого додатка - це вкладка, і я хочу приховати ключове слово під час перемикання вкладок - я отримую токен вікна у вікні tabHost View.

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 0);
    }
}

128



Я отримав це для роботи з SearchView теж. Дивіться нижче для моєї відповіді. Спасибі motsoss! - Azurespot


Спробуйте скористатись цим кодом нижче onCreate()

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

115



Цей метод працює як засіб обійти помилку "не можна сховати м'яку клавіатуру" в 2.0 та 2.1, як описано в code.google.com/p/android/issues/detail?id=7115 ... метод hideSoftInputFromWindow, перерахований вище, не працював, коли я спробував це, але editView.setInputType (0) зробив. - Spike Williams
Це legit для Javadoc (не рубати), хоча я б переписав метод як editView.setInputType(InputType.TYPE_NULL); - Bostone
це працює, однак, він приховує андроїд: натяк. я використовую Android 1.5 - Tirtha
@Bostone Це не працює для SearchView - nmxprime
це чудово підходить, коли вам потрібно закрити клавіатуру з діалогового вікна, не потрібно отримувати екземпляр або що-небудь, і може призначити це всім текстам редагування, коли користувач натискає кнопку, яка закриває діалогове вікно - I'm_With_Stupid


Оновлення: Я не знаю, чому це рішення більше не працює (я просто протестував на Android 23). Будь ласка, використовуйте рішення Саурах Парек замість цього. Ось:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

Стара відповідь:

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

108



Де я повинен розмістити цей код? Я намагався вставити getWindow (). SetSoftInputMode (WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); в onCreate (), але клавіатура ніколи не приховується - user2236096
не працює, перевірено в radioGroup.setOnCheckedChangeListener, API 23 - Christian Schäfer
Якщо ви подивитеся ближче, InputMethodManager.HIDE_IMPLICIT_ONLY та InputMethodManager.SHOW_IMPLICIT мають таке ж значення, що і "1", так що немає різниці між цими викликами. => не працює - Palejandro
якщо викликати imm.toggleSoftInput (InputMethodManager.HIDE_IMPLICIT_ONLY, 0); то клавіатура покаже на екрані :) Краща реалізація: github.com/ravindu1024/android-keyboardlistener Слава на Android SDK - Duna
I don't know why this solution is not work any more - тому що це Android, все може змінитись, можливо, частково з поганого дизайну ... Ми пишемо недбало, потім ми викреслюємо все і переписуємо все. - King King