экранную - Закройте/спрячьте мягкую клавиатуру Android




скрыть клавиатуру android studio (20)

Короткий ответ

В вашем прослушивателе OnClick вызывается onEditorAction из EditText с IME_ACTION_DONE

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

Развертывание

Я считаю, что этот метод лучше, проще и более согласован с шаблоном проектирования Android. В простом примере выше (и, как правило, в большинстве распространенных случаев) у вас будет EditText который имеет / имел фокус, и он также обычно вызывал клавиатуру в первую очередь (она, безусловно, может вызвать ее в многие распространенные сценарии). Таким же образом, он должен освободить клавиатуру, обычно это может быть сделано ImeAction . Просто посмотрите, как ведет себя EditText с android:imeOptions="actionDone" , вы хотите добиться того же поведения теми же средствами.

Проверьте этот ответ

В моем макете есть EditText и Button .

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


Вы можете заставить 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 в качестве второго параметра, чтобы убедиться, что вы скрываете клавиатуру, когда пользователь явно не заставлял ее отображаться (удерживая меню).

Примечание. Если вы хотите сделать это в Kotlin, используйте: context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager


Попробуйте этот ниже код в onCreate()

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

Решение Мейера работает и для меня. В моем случае верхний уровень моего приложения - tabHost, и я хочу скрыть ключевое слово при переключении вкладок - я получаю маркер окна из tabHost View.

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

У меня есть еще одно решение скрыть клавиатуру:

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

Здесь передайте HIDE_IMPLICIT_ONLY в позиции showFlag и 0 в позиции hiddenFlag . Он будет принудительно закрывать мягкую клавиатуру.


Чтобы помочь прояснить это безумие, я хотел бы начать с извинения от имени всех пользователей Android за простое смешное обращение с Google к мягкой клавиатуре. Причина в том, что так много ответов, по-разному, по одному и тому же вопросу, потому что этот API, как и многие другие в Android, ужасно разработан. Я не могу придумать ни одного вежливого способа заявить об этом.

Я хочу скрыть клавиатуру. Я ожидаю, что Android предоставит следующее заявление: Keyboard.hide() . Конец. Большое спасибо. Но у Android есть проблемы. Вы должны использовать InputMethodManager чтобы скрыть клавиатуру. Хорошо, отлично, это API Android на клавиатуре. НО! У вас должен быть Context , чтобы получить доступ к IMM. Теперь у нас есть проблема. Я могу скрыть клавиатуру от статического или служебного класса, который не нужен или нужен для любого Context . или И еще хуже, IMM требует, чтобы вы указали, какой View (или, что еще хуже, какой Window ) вы хотите скрыть клавиатуру FROM.

Это то, что скрывает клавиатуру так сложно. Дорогой Google: Когда я ищу рецепт для пирога, на Земле нет RecipeProvider , который откажется предоставить мне рецепт, если я не отвечу сначала, что торт будет съеден И где он будет съеден !!

Эта печальная история заканчивается уродливой правдой: чтобы скрыть клавиатуру Android, вам потребуется предоставить две формы идентификации: Context и либо View либо 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

Это не сработает, потому что вы передадите ссылку на хост- Activity Fragment , которая не будет иметь сфокусированного управления, пока отображается 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 (обычно мягкая клавиатура) будет реагировать на событие фокусировки, показывая себя. windowSoftInputMode в AndroidManifest.xml , когда установлен в stateAlwaysHidden , указывает клавиатуре игнорировать этот автоматически назначенный начальный фокус.

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

Практически невероятно, кажется, ничего не делает, чтобы клавиатура не открывалась, когда вы касаетесь focusable="false" управления (если контрольный элемент не назначен 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();

ОБНОВЛЕНИЕ 2: очистить фокус, чтобы снова не показывать клавиатуру, если вы открываете приложение из фона

Добавьте эту строку в конец метода:

view.clearFocus();


Я использую пользовательскую клавиатуру для ввода шестнадцатеричного номера, поэтому я не могу открыть клавиатуру IMM ...

В v3.2.4_r1 setSoftInputShownOnFocus(boolean show) был добавлен для управления погодой или не отображать клавиатуру, когда TextView получает фокус, но ее все еще скрыто, поэтому необходимо использовать отражение:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

Для более старых версий я получил очень хорошие результаты (но далеко не идеальный) с помощью OnGlobalLayoutListener , добавленный с помощью ViewTreeObserver из моего корневого представления, а затем проверяя, показана ли клавиатура следующим образом:

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

Это последнее решение может отображать клавиатуру в течение секунды секунды и беспорядок с помощью дескрипторов выделения.

Когда клавиатура входит в полноэкранный режим, onGlobalLayout не вызывается. Чтобы этого избежать, используйте TextView#setImeOptions(int) или в XML-декларации TextView:

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

Обновление: просто нашел, какие диалоги используют, чтобы никогда не показывать клавиатуру и работать во всех версиях:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

Я провел более двух дней, работая над всеми решениями, размещенными в потоке, и обнаружил, что их так или иначе не хватает. Мое точное требование состоит в том, чтобы иметь кнопку, которая со 100% -й надежностью покажет или скроет экранную клавиатуру. Когда клавиатура находится в скрытом состоянии, она не должна появляться повторно, независимо от того, какие поля ввода пользователь нажимает. Когда он находится в своем видимом состоянии, клавиатура не должна исчезать независимо от того, какие кнопки пользователь нажимает. Это должно работать на Android 2.2+ вплоть до новейших устройств.

Вы можете увидеть эту реализацию в моем чистом RPN приложении.

После тестирования многих предложенных ответов на нескольких разных телефонах (включая устройства froyo и gingerbread) стало очевидно, что приложения для Android могут быть надежно:

  1. Временно скройте клавиатуру. Он снова появится снова, когда пользователь сфокусирует новое текстовое поле.
  2. Покажите клавиатуру, когда начинается действие, и установите флажок в действии, указывающий, что клавиатура всегда должна быть видимой. Этот флаг может быть установлен только при инициализации активности.
  3. Отметьте действие, чтобы никогда не показывать или не допускать использование клавиатуры. Этот флаг может быть установлен только при инициализации активности.

Для меня временно скрывать клавиатуру недостаточно. На некоторых устройствах он снова появится, как только будет сфокусировано новое текстовое поле. Поскольку мое приложение использует несколько текстовых полей на одной странице, фокусировка на новом текстовом поле приведет к тому, что скрытая клавиатура снова появится снова.

К сожалению, пункты 2 и 3 в списке работают только надёжно, когда начинается действие. Как только активность станет видимой, вы не сможете надолго скрыть или показать клавиатуру. Хитрость заключается в том, чтобы фактически перезапустить свою активность, когда пользователь нажимает кнопку переключения клавиатуры. В моем приложении, когда пользователь нажимает кнопку переключения клавиатуры, выполняется следующий код:

private void toggleKeyboard(){

    if(keypadPager.getVisibility() == View.VISIBLE){
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, true);
        i.putExtras(state);

        startActivity(i);
    }
    else{
        Intent i = new Intent(this, MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
        Bundle state = new Bundle();
        onSaveInstanceState(state);
        state.putBoolean(SHOW_KEYBOARD, false);
        i.putExtras(state);

        startActivity(i);
    }
}

Это заставляет текущую активность сохранять свое состояние в Bundle, а затем запускается активность, проходя через логическое значение, указывающее, следует ли показывать или скрывать клавиатуру.

Внутри метода onCreate выполняется следующий код:

if(bundle.getBoolean(SHOW_KEYBOARD)){
    ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(newEquationText,0);
    getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
}
else{
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
            WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
}

Если нужно отобразить мягкую клавиатуру, то InputMethodManager будет предложено отобразить клавиатуру, и в окне указывается, что мягкий вход всегда отображается. Если мягкая клавиатура должна быть скрыта, то устанавливается WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM.

Этот подход надежно работает на всех устройствах, на которых я тестировал: от 4-летнего телефона HTC, работающего под управлением Android 2.2 до версии 7, работающей под управлением 4.2.2. Единственным недостатком такого подхода является то, что вам нужно быть осторожным при обращении с кнопкой «Назад». Поскольку у моего приложения есть только один экран (его калькулятор), я могу переопределить onBackPressed () и вернуться на главный экран устройства.


Обновление: я не знаю, почему это решение больше не работает (я только что тестировал на Android 23). Вместо этого используйте решение Saurabh Pareek . Вот:

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);

Вот как вы это делаете в Mono для Android (AKA MonoDroid)

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

Просто используйте этот оптимизированный код в своей деятельности:

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

У Saurabh Pareek есть лучший ответ.

Тем не менее, можно использовать правильные флаги.

/* hide keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

/* show keyboard */
((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
    .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

Пример реального использования

/* click button */
public void onClick(View view) {      
  /* hide keyboard */
  ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
      .toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

  /* start loader to check parameters ... */
}

/* loader finished */
public void onLoadFinished(Loader<Object> loader, Object data) {
    /* parameters not valid ... */

    /* show keyboard */
    ((InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE))
        .toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);

    /* parameters valid ... */
}

Я почти попробовал все эти ответы, у меня были некоторые случайные проблемы, особенно с галактикой s5 ssung.

Я в конечном итоге заставляю шоу и скрывать, и он отлично работает:

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

использовать этот

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

В качестве альтернативы этому решению все вокруг , если вы хотите закрыть мягкую клавиатуру из любого места, не имея ссылки на поле (EditText), которое было использовано для открытия клавиатуры, но все же захотелось сделать это, если поле было сфокусировано, вы могли бы использовать это (из Activity):

if (getCurrentFocus() != null) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}

В некоторых случаях эти методы могут работать, кроме всех остальных. Это экономит мой день :)

public static void hideSoftKeyboard(Activity activity) {
    if (activity != null) {
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (activity.getCurrentFocus() != null && inputManager != null) {
            inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
            inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

public static void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}

Для моего случая я использовал SearchView в панели действий. После того, как пользователь выполнит поиск, клавиатура снова откроется.

Использование InputMethodManager не закрывало клавиатуру. Мне пришлось очиститьфокус и настроить фокусное изображение поиска на false:

mSearchView.clearFocus();
mSearchView.setFocusable(false);

Добавьте в свою активность android:windowSoftInputMode="stateHidden"файл манифеста. Пример:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>

У меня есть случай, где мой EditTextможет находиться и в a AlertDialog, поэтому клавиатура должна быть закрыта при увольнении. Следующий код, кажется, работает где угодно:

public static void hideKeyboard( Activity activity ) {
    InputMethodManager imm = (InputMethodManager)activity.getSystemService( Context.INPUT_METHOD_SERVICE );
    View f = activity.getCurrentFocus();
    if( null != f && null != f.getWindowToken() && EditText.class.isAssignableFrom( f.getClass() ) )
        imm.hideSoftInputFromWindow( f.getWindowToken(), 0 );
    else 
        activity.getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN );
}

protected void hideSoftKeyboard(EditText input) {
    input.setInputType(0);
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}






soft-keyboard