Android - Hide keyboard on Android 8

2019-04-03 22:42发布

问题:

I'm having troubles with hiding the keyboard on Android 8. I used this before and it worked for the older androids:

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

Android 8 just ignores it and shows the keyboard anyway. Probably making the input field unfocusable would help, but I really need it to be focusable, so this is not an option.

回答1:

Instead of hideSoftInputFromWindow you can use toggleSoftInput.

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

works for Android 8 on the emulator at least



回答2:

The @EarlOfEgo 's solution caused some troubles on older Android versions. This is the ideal solution, which works perfectly on all (at least almost) Android versions:

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


回答3:

Try this line in Manifest within Activity tag:

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


回答4:

Here you have two static functions to hide keyboard, depend on your case which one you want to use. I tested on Android Oreo and it works.

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

Example of use:

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

To show:

    UIHelper.showKeyboard(this, passwordField)


回答5:

I had a similar problem and I solved it like this:

class MainActivity : Activity() {

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

    }
}

This is not the most elegant solution. But in my situation it was acceptable



回答6:

Use this method I have created

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


回答7:

I had the same issue recently, and worked around it by providing the root view from (in my case) the fragment for the window token instead of the activity's current focus.

This way, the keyboard is dismissed, and focus in the EditText is maintained.

Tested on Pixel 2 XL running 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)
}


回答8:

Hide keyboard inside runnable, with calling post method of your view:

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


回答9:

just try this method to intercept the focus event and hide the softkeyboard:

@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.
    }
}