Android - Скрыть клавиатуру на Android 8

У меня проблемы со скрытием клавиатуры на Android 8. Я использовал это раньше, и это сработало для старых андроидов:

    val view = activity.currentFocus
    if (view != null) {
        val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }

Android 8 просто игнорирует его и все равно показывает клавиатуру. Вероятно, сделать поле ввода нецелесообразным поможет, но мне действительно нужно, чтобы он был сфокусированным, поэтому это не вариант.

Ответ 1

Решение @EarlOfEgo вызвало некоторые проблемы на старых версиях Android. Это идеальное решение, которое отлично работает на всех (по крайней мере почти) версиях Android:

protected fun hideKeyboard() {
    val view = activity.currentFocus
    if(android.os.Build.VERSION.SDK_INT >= 26) {
        val imm: InputMethodManager = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        view?.post({
            imm.hideSoftInputFromWindow(activity.currentFocus.windowToken, 0)
            imm.hideSoftInputFromInputMethod(activity.currentFocus.windowToken, 0)
        })
    } else {
        if (view != null) {
            val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(view.windowToken, 0)
            imm.hideSoftInputFromInputMethod(view.windowToken, 0)
        }
    }
}

Ответ 2

Вместо hideSoftInputFromWindow вы можете использовать toggleSoftInput.

val imm: InputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
if (imm.isActive)
     imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)

работает на Android 8 на эмуляторе как минимум

Ответ 3

Попробуйте эту строку в Manifest в пределах Activity тега:

<activity
         android:name=".Activity"
         android:windowSoftInputMode="stateHidden"/>

Ответ 4

Здесь у вас есть две статические функции для скрытия клавиатуры, в зависимости от вашего случая, какую вы хотите использовать. Я тестировал на Android Oreo и все работает.

object UIHelper {

            fun hideSoftKeyboard(activity: Activity?) {
                if (activity != null) {
                    val inputManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    if (activity.currentFocus != null && inputManager != null) {
                        inputManager.hideSoftInputFromWindow(activity.currentFocus!!.windowToken, 0)
                        inputManager.hideSoftInputFromInputMethod(activity.currentFocus!!.windowToken, 0)
                    }
                }
            }

            fun hideSoftKeyboard(view: View?) {
                if (view != null) {
                    val inputManager = view!!.getContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputManager?.hideSoftInputFromWindow(view!!.getWindowToken(), 0)
                }
            }

            fun showKeyboard(activityContext: Context, editText: EditText) {
                editText.requestFocus()
                Handler().postDelayed(Runnable {
                    val inputMethodManager = activityContext.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
                    inputMethodManager.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT)
                }, 250)
            }
        }

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

  1. UIHelper.hideSoftKeyboard(this)
  2. UIHelper.hideSoftKeyboard(passwordField)

Показывать:

    UIHelper.showKeyboard(this, passwordField)

Ответ 5

Недавно у меня была такая же проблема, и я работал над ней, предоставив корневой вид из (в моем случае) фрагмента для токена окна вместо текущего фокуса активности.

Таким образом, клавиатура увольняется, и фокусировка в EditText поддерживается.

Протестировано на Pixel 2 XL под управлением Android 8.1:

/**
 * Hides the Soft Keyboard on demand
 *
 * @param activity the activity from which to get the IMM
 * @param view the view from which to provide a windowToken
 */
fun hideSoftKeyboard(activity: Activity, view: View?) {
    val inputMethodManager = activity.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.hideSoftInputFromWindow(view?.windowToken, 0)
}

Ответ 6

У меня была аналогичная проблема, и я решил это следующим образом:

class MainActivity : Activity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        window.setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)

    }
}

Это не самое элегантное решение. Но в моей ситуации это было приемлемо

Ответ 7

Используйте этот метод, который я создал

    public static void showHideInput(Context context,boolean visibility, View view){

    if (view != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (visibility) imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
        else imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }
}

Ответ 8

Скрывать клавиатуру внутри runnable, используя метод вызова post вашего вида:

view.post(() -> {
   hideKeyboard(view);
}

Ответ 9

просто попробуйте этот метод, чтобы перехватить событие фокуса и скрыть экранную панель:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);

    if (hasFocus) {
        View lFocused = getCurrentFocus();
        if (lFocused != null)
            lFocused.postDelayed(new Runnable() {
                @Override
                public void run() {
                    InputMethodManager lInputManager = (InputMethodManager) pContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                    lInputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
                }
            }, 100);//Modified to 100ms to intercept SoftKeyBoard on Android 8 (Oreo) and hide it.
    }
}