Reputation: 42984
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
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
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
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
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
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
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
Reputation: 3738
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
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
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
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())
Upvotes: 1
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
Reputation: 22832
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)
}
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
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
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
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
Reputation: 479
Just add this property in your EditTect
view to hide the keyboard.
android:focusable="false"
Upvotes: -10
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
Reputation: 419
An easy way for you is to set the below attribute in your EditText View.
android:imeOptions="actionDone"
Upvotes: -1
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
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
Reputation: 129
Try this:
Force fully the Android soft input keyboard:
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null)
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
Upvotes: 1
Reputation: 142
An easy workaround is to just editText.setEnabled(false);editText.setEnabled(true);
in your Button onClick()
method.
Upvotes: 2
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
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
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
Reputation: 49
To close or hide the Android soft keyboard programmatically, you can use the following methods:
Using InputMethodManager:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
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;
} });
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
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
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
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
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