Vidar Vestnes
Vidar Vestnes

Reputation: 42984

How can I close/hide the Android soft keyboard programmatically?

I have an EditText and a Button in my layout.

After writing in the edit field and clicking on the Button, I want to hide the virtual keyboard when touching outside the keyboard. Can someone provide a simple example of how to achieve this?

Upvotes: 4370

Views: 1868447

Answers (30)

Abhay kumar bhumihar
Abhay kumar bhumihar

Reputation: 349

Hide Keyboard from an Activity

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

Hide Keyboard from a Fragment

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

}

Hide Keyboard After User Interaction

button.setOnClickListener {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus?.windowToken, 0)

}

Hide Keyboard Without a View Reference

fun hideKeyboard() {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0)

}

Hide Keyboard When Navigating Between Fragments or Activities

override fun onPause() {
super.onPause()
hideKeyboard() // Call the hide keyboard function here

}

Hide Keyboard Using an Extension Function

fun Activity.hideKeyboard() {
val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
val view = this.currentFocus ?: View(this)
imm.hideSoftInputFromWindow(view.windowToken, 0)

}

Upvotes: 2

Abhay kumar bhumihar
Abhay kumar bhumihar

Reputation: 349

Use this code :-

fun hideStatusBar(activity: Activity) {
                    if (Build.VERSION.SDK_INT < 16) {
                        activity.window.setFlags(
                            WindowManager.LayoutParams.FLAG_FULLSCREEN,
                            WindowManager.LayoutParams.FLAG_FULLSCREEN
                        )
                    } else {
                        val decorView: View = activity.window.decorView
                        // Hide Status Bar.
                        val uiOptions = View.SYSTEM_UI_FLAG_FULLSCREEN
                        decorView.systemUiVisibility = uiOptions
                    }
                }

Upvotes: 0

Khush Parmar
Khush Parmar

Reputation: 561

Here is the best solution by creating the Extension function for the same and just call this function after the setContentView in onCreate of your activity to remove more code for managing every EditText in your activity to hide the keyboard when clicked outside, if you have multiple EditText. This single function can manage all the EditText and reduce the overhead code to manage multiple.

fun Activity.setUpUI(view: View) {
    // Set up touch listener for non-text box views to hide keyboard.

    if (view !is EditText) {
        view.setOnTouchListener { _, _ ->
            val inputMethodManager =
                this.getSystemService(
                    Activity.INPUT_METHOD_SERVICE
                ) as InputMethodManager
            if (inputMethodManager.isAcceptingText) {
                inputMethodManager.hideSoftInputFromWindow(
                    this.currentFocus?.windowToken,
                    0
                )
            }
            false
        }
    }

    //If a layout container, iterate over children and seed recursion.
    if (view is ViewGroup) {
        for (i in 0 until view.childCount) {
            val innerView = view.getChildAt(i)
            this.setUpUI(innerView)
        }
    }
}

Call the extension function in your activity like below :

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivitySignUpBinding.inflate(layoutInflater)
    setContentView(binding.root)
    this.setUpUI(binding.root)
}

Upvotes: 0

Sergey Chilingaryan
Sergey Chilingaryan

Reputation: 161

Thank God it’s officially supported after 11 years.

First add dependency implementation 'androidx.core:core-ktx:1.7.0' to app gradle.

Then get InsetsController from ViewCompat or WindowCompat class.

Finally use hide() and show() function of InsetsController

Add support for Dialog. Available in BottomSheetDialog. @Rondev. Using a safer way to get activity instead of directly cast from context.

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment

fun View.showKeyboard() = ViewCompat.getWindowInsetsController(this)?.show(WindowInsetsCompat.Type.ime())
fun View.hideKeyboard() = ViewCompat.getWindowInsetsController(this)?.hide(WindowInsetsCompat.Type.ime())

fun Dialog.showKeyboard() = window?.decorView?.showKeyboard()
fun Dialog.hideKeyboard() = window?.decorView?.hideKeyboard()

fun Context.showKeyboard() = getActivity()?.showKeyboard()
fun Context.hideKeyboard() = getActivity()?.hideKeyboard()

fun Fragment.showKeyboard() = activity?.showKeyboard()
fun Fragment.hideKeyboard() = activity?.hideKeyboard()

fun Activity.showKeyboard() = WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.ime())
fun Activity.hideKeyboard() = WindowCompat.getInsetsController(window, window.decorView)?.hide(WindowInsetsCompat.Type.ime())

fun Context.getActivity(): Activity? {
    return when (this) {
        is Activity -> this
        is ContextWrapper -> this.baseContext.getActivity()
        else -> null
    }
}

Old anwser below

Here is the simple project on github

import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment

fun View.showKeyboard() = ViewCompat.getWindowInsetsController(this)?.show(WindowInsetsCompat.Type.ime())
fun View.hideKeyboard() = ViewCompat.getWindowInsetsController(this)?.hide(WindowInsetsCompat.Type.ime())

fun Dialog.showKeyboard() = window?.decorView?.showKeyboard()
fun Dialog.hideKeyboard() = window?.decorView?.hideKeyboard()

fun Context.showKeyboard() = getActivity()?.showKeyboard()
fun Context.hideKeyboard() = getActivity()?.hideKeyboard()

fun Fragment.showKeyboard() = activity?.showKeyboard()
fun Fragment.hideKeyboard() = activity?.hideKeyboard()

fun Activity.showKeyboard() = WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.ime())
fun Activity.hideKeyboard() = WindowCompat.getInsetsController(window, window.decorView)?.hide(WindowInsetsCompat.Type.ime())

fun Context.getActivity(): Activity? {
    return when (this) {
        is Activity -> this
        is ContextWrapper -> this.baseContext.getActivity()
        else -> null
    }
}

Upvotes: 52

Rizwan Ahmed
Rizwan Ahmed

Reputation: 334

In Kotlin, just use these two methods to show and hide the keyboard.

fun showKeyboard() =
    (context.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as? InputMethodManager)!!
        .toggleSoftInput(InputMethodManager.SHOW_FORCED, 0)

fun hideKeyboard(view: View) =
    (context.getSystemService(AppCompatActivity.INPUT_METHOD_SERVICE) as? InputMethodManager)!!
        .hideSoftInputFromWindow(view.windowToken, 0)

Here view is your current view.

Upvotes: 5

Abrar Malekji
Abrar Malekji

Reputation: 111

There are a lot of answers. If after all nothing works then, here is a tip :),

You can make an EditText and,

edittext.setAlpha(0f);

this edittext will not be seen because of the alpha method. Now use the Above answers on how to show/hide soft keyboard with EditText.

Upvotes: 0

Mattia Ferigutti
Mattia Ferigutti

Reputation: 3738

A Kotlin solution in a fragment

fun hideSoftKeyboard() {
        val view = activity?.currentFocus
        view?.let { v ->
            val imm =
                activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager // or context
            imm.hideSoftInputFromWindow(v.windowToken, 0)
        }
}

Check your manifest doesn't have this parameter associated with your activity:

android:windowSoftInputMode="stateAlwaysHidden"

Upvotes: 6

niek tuytel
niek tuytel

Reputation: 1179

If you set in your .xml android:focused="true", then it would not work, because it is a set like it is not changeable.

So the solution:

android:focusedByDefault="true"

Then it will set it once and can hide or show the keyboard.

Upvotes: 1

Ayan Bhattacharjee
Ayan Bhattacharjee

Reputation: 515

This one works for me. You just need to pass the element inside it.

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

Upvotes: 2

Jaydeep chatrola
Jaydeep chatrola

Reputation: 2711

There is a new API in Android 11 called WindowInsetsController. Apps can get access to a controller from any view, by which we can use the hide() and show() methods:

val controller = view.windowInsetsController

// Show the keyboard (IME)
controller.show(Type.ime())

// Hide the keyboard
controller.hide(Type.ime())

See WindowInsetsController

Upvotes: 1

Pankaj Kumar
Pankaj Kumar

Reputation: 83028

Using Android 10, we are going to get an amazing way to show and hide keyboards. Read the Release Notes - 1.5.0-alpha02. Now how to hide or show the keyboard:

val controller = view.windowInsetsController

// Show the keyboard
controller.show(Type.ime())
// Hide the keyboard
controller.hide(Type.ime())

Linking my own answer How to check visibility of software keyboard in Android? and an Amazing blog which includes more of this change (even more than it).

Upvotes: 8

aminography
aminography

Reputation: 22832

Kotlin version via an extension function

Using Kotlin extension functions, it'd be so simple to show and hide the soft keyboard.

ExtensionFunctions.kt

import android.app.Activity
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.fragment.app.Fragment

fun Activity.hideKeyboard(): Boolean {
    return (getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow((currentFocus ?: View(this)).windowToken, 0)
}

fun Fragment.hideKeyboard(): Boolean {
    return (context?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow((activity?.currentFocus ?: View(context)).windowToken, 0)
}

fun EditText.hideKeyboard(): Boolean {
    return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .hideSoftInputFromWindow(windowToken, 0)
}

fun EditText.showKeyboard(): Boolean {
    return (context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager)
        .showSoftInput(this, 0)
}

Usage

Now in your Activity or Fragment, hideKeyboard() is clearly accessible as well as calling it from an instance of EditText like:

editText.hideKeyboard()

Upvotes: 16

Davinder Goel
Davinder Goel

Reputation: 853

You can hide the keyboard in Kotlin as well using this code snippet.

 fun hideKeyboard(activity: Activity?) {
    val inputManager: InputMethodManager? = 
    activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? 
    InputMethodManager
    // Check if no view has focus:
    val v = activity?.currentFocus ?: return
    inputManager?.hideSoftInputFromWindow(v.windowToken, 0)
 }

Upvotes: 1

Kalpesh Rupani
Kalpesh Rupani

Reputation: 1049

By adding the generic method to your utility or helper class. By just calling itself, you can hide and show the keyboard:

fun AppCompatActivity.hideKeyboard() {
    val view = this.currentFocus
    if (view != null) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
}

fun AppCompatActivity.showKeyboard() {
    val view = this.currentFocus
    if (view != null) {
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(view.windowToken, 0)
    }
    window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
}

Upvotes: 3

Junaid Bashir
Junaid Bashir

Reputation: 172

Just call the below method. It will hide your keyboard if it’s showing.

public void hideKeyboard() {
    try {
        InputMethodManager inputmanager = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputmanager != null) {
            inputmanager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);
        }
    } 
    catch (Exception var2) {
    }
}

Upvotes: 9

Abdullah Nagori
Abdullah Nagori

Reputation: 479

Just add this property in your EditTect view to hide the keyboard.

android:focusable="false"

Upvotes: -10

Sanket Naik
Sanket Naik

Reputation: 196

For Kotlin lovers. I have created two extension functions. For hideKeyboard fun, you can pass edittext's instance as a view.

fun Context.hideKeyboard(view: View) {
    (getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
        hideSoftInputFromWindow(view.windowToken, 0)
    }
}

fun Context.showKeyboard() {
    (getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager)?.apply {
        toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
    }
}

Upvotes: 7

Marium Jawed
Marium Jawed

Reputation: 419

An easy way for you is to set the below attribute in your EditText View.

android:imeOptions="actionDone"

Upvotes: -1

norbDEV
norbDEV

Reputation: 5365

This works in a fragment with Android 10 (API 29):

val activityView = activity?.window?.decorView?.rootView
activityView?.let {
    val imm = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as? InputMethodManager
    imm?.hideSoftInputFromWindow(it.windowToken, 0)
}

Upvotes: 1

Salman Nazir
Salman Nazir

Reputation: 2837

I use Kotlin extensions for showing and hiding the keyboard.

fun View.showKeyboard() {
  this.requestFocus()
  val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  inputMethodManager.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
}

fun View.hideKeyboard() {
  val inputMethodManager = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
  inputMethodManager.hideSoftInputFromWindow(windowToken, 0)
}

Upvotes: 3

Rahul Patil
Rahul Patil

Reputation: 129

Try this:

Force fully the Android soft input keyboard:

Create a method in a helper class

InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

Upvotes: 1

KarlTheGreat
KarlTheGreat

Reputation: 142

An easy workaround is to just editText.setEnabled(false);editText.setEnabled(true); in your Button onClick() method.

Upvotes: 2

Bhavik Nathani
Bhavik Nathani

Reputation: 499

Just add the following line in AndroidManifest in the specific activity.

<activity
    android:name=".MainActivity"
    android:screenOrientation="portrait"
    android:windowSoftInputMode="adjustPan"/>

Upvotes: 5

BaldrSky
BaldrSky

Reputation: 21

My solution:

Construct it with an activity (a view is optional), use a handler to post this (with some delay, for example, 100 ms is better). Directly calling the input manager will not work sometimes. It only works while we can get the Activity. I think it is normal.

If you can get your root viewgroup or editview when you call. Just send it in for a better result.

public class CloseSoftKeyboardRunnable implements Runnable
{
    Activity activity;
    View view;  // For dialog will occur context getcurrentfocus == null. send a rootview to find currentfocus.

    public CloseSoftKeyboardRunnable(Activity activity, View view)
    {
        this.activity = activity;
        this.view = view;
    }

    public CloseSoftKeyboardRunnable(Activity activity)
    {
        this.activity = activity;
    }
    @Override
    public void run() {
        if (!activity.isFinishing())
        {
            InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);

            if (view == null) {
                view = activity.getCurrentFocus();
            }
            else
            {
                try {
                    view = ((ViewGroup)view).getFocusedChild();
                }
                catch ( Exception e) {}
            }

            Window window =  activity.getWindow();

            if (window != null)
            {
                if (view == null) {
                    try {
                        view = window.getDecorView();
                        view = ((ViewGroup)view).getFocusedChild();
                    }
                    catch ( Exception e) {}
                }

                if (view == null) {
                    view = window.getDecorView();
                }

                if (view != null) {
                    if (view instanceof EditText)
                    {
                        EditText edittext = ((EditText) view);
                        edittext.setText(edittext.getText().toString()); // Reset edit text bug on some keyboards bug
                        edittext.clearFocus();
                    }

                    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
                }
                window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
            }
        }
    }
}

Upvotes: 0

Morteza Allahyari
Morteza Allahyari

Reputation: 1120

You can use the extensions below to hide and show the soft keyboard:

fun Fragment.showKeyboard(view: View) {
    view.isFocusableInTouchMode = true
    view.requestFocus()
    val imm = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE)
        as InputMethodManager
    imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT) }

fun Fragment.hideKeyboard(view: View) {
    view.clearFocus()
    val imm = view.context?.getSystemService(Context.INPUT_METHOD_SERVICE)
       as InputMethodManager
    imm.hideSoftInputFromWindow(view.windowToken, 0) }

To call the extension, you can simply follow the below in your fragments:

showKeyboard(Your edittext ID)

hideKeboard(Your edittext ID)

Upvotes: 0

Jignesh Hadiya
Jignesh Hadiya

Reputation: 49

To close or hide the Android soft keyboard programmatically, you can use the following methods:

  1. Using InputMethodManager:

     InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
     imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
    
  2. Using View's onEditorAction:

    If you have an EditText view and want to hide the soft keyboard when the user presses the "Done" or "Enter" key, you can use the onEditorAction listener:

     yourEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
         @Override
         public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
             if (actionId == EditorInfo.IME_ACTION_DONE) {
                 InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                 imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
                 return true;
             }
             return false;
         } });
    
  3. Programmatically clear focus:

    Another approach is to programmatically clear focus from the EditText view, which will cause the soft keyboard to be hidden:

     yourEditText.clearFocus();
    

    Remember to replace yourEditText with the actual reference to your EditText view. Also, make sure you have the appropriate permissions declared in your Android manifest file, specifically android.permission.INPUT_METHOD.

These methods will allow you to programmatically hide the soft keyboard on an Android device.

Upvotes: 3

Eeman
Eeman

Reputation: 175

You can simply add OnFocusChangeListener to the your view. For example, editText in this case.

editText.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
        if (!hasFocus) {
           val imm = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
           val focusedView = currentFocus
           if (imm != null && focusedView != null) {
              imm.hideSoftInputFromWindow(focusedView.windowToken, 0)
           }
        }
    }

Upvotes: 0

Dragan Stojanov
Dragan Stojanov

Reputation: 530

I tried this. Works well, tested on Nougat API 24.

import android.app.Activity
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment


fun Activity.hideKeyboard() {
    getInsetController().hide((WindowInsetsCompat.Type.ime()))
}

fun Activity.showKeyboard() {
    getInsetController().show((WindowInsetsCompat.Type.ime()))
}

fun Fragment.hideKeyboard() {
    requireActivity().getInsetController().hide((WindowInsetsCompat.Type.ime()))
}

fun Fragment.showKeyboard() {
    requireActivity().getInsetController().show((WindowInsetsCompat.Type.ime()))
}

fun Activity.getInsetController() = WindowCompat.getInsetsController(window, window.decorView)

Upvotes: 1

gmk57
gmk57

Reputation: 939

Now, almost 12 years later, we finally have an official, backwards compatible way to do this with AndroidX Core 1.5+:

fun View.hideKeyboard() = ViewCompat.getWindowInsetsController(this)
    ?.hide(WindowInsetsCompat.Type.ime())

or specifically for Fragment:

fun Fragment.hideKeyboard() = ViewCompat.getWindowInsetsController(requireView())
    ?.hide(WindowInsetsCompat.Type.ime())

Upvotes: 37

Akshay
Akshay

Reputation: 103

Kotlin Version:

fun showKeyboard(mEtSearch: EditText, context: Context) {
        mEtSearch.requestFocus()
        val imm: InputMethodManager =
            context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.showSoftInput(mEtSearch, 0)
}

Upvotes: 0

Related Questions