I have an EditText
called myTextview
. I want the soft keyboard to show when I click on the EditText
but then dismiss if I click outside of
use following code.
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
it's working for me.
For all those who are looking for a Xamarin Android code for this :
public override bool DispatchTouchEvent(MotionEvent ev)
{
try
{
View view = CurrentFocus;
if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("android.webkit."))
{
int[] Touch = new int[2];
view.GetLocationOnScreen(Touch);
float x = ev.RawX + view.Left - Touch[0];
float y = ev.RawY + view.Top - Touch[1];
if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom)
((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0);
}
}
catch (System.Exception ex)
{
}
return base.DispatchTouchEvent(ev);
}
Touch event on a View will start with ACTION_DOWN
from being passed from top to this View in view hierachy. Override dispatchTouchEvent
to do additional things. Here's an example to extend from FrameLayout
in kotlin:
class TLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null):
FrameLayout(context, attrs){
var preDispatchTouchEvent: ((ev: MotionEvent?)->Boolean)? = null
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (preDispatchTouchEvent==null || !preDispatchTouchEvent!!.invoke(ev)) {
super.dispatchTouchEvent(ev)
}
return true
}
}
Wrap your EditText
and other relative View
s under this layout, and set preDispatchTouchEvent
to dismiss EditText
when event is not above it.
Check this OS question and official doc to have deeper understanding of touch event delivering.
I found a better solution:
Override the dispatchTouchEvent
method in your Activity.
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
View v = getCurrentFocus();
if (v != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) &&
v instanceof EditText &&
!v.getClass().getName().startsWith("android.webkit.")) {
int[] sourceCoordinates = new int[2];
v.getLocationOnScreen(sourceCoordinates);
float x = ev.getRawX() + v.getLeft() - sourceCoordinates[0];
float y = ev.getRawY() + v.getTop() - sourceCoordinates[1];
if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom()) {
hideKeyboard(this);
}
}
return super.dispatchTouchEvent(ev);
}
private void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null) {
activity.getWindow().getDecorView();
InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0);
}
}
}
This is applicable even if you are working with webview.
UPDATE 10th July 2020
The above method works perfectly but the EditText is still has the focus and typing cursor is still visible.
To solve the described issue. Do this
Add
findViewById(android.R.id.content).setFocusableInTouchMode(true);
in your onCreate() method
Add findViewById(android.R.id.content).clearFocus();
in the
hideKeyboard()
method
Credit to Eddwhis's comment
Plea: I recognize I have no clout, but please take my answer seriously.
Problem: Dismiss soft keyboard when clicking away from keyboard or edit text with minimal code.
Solution: External library known as Butterknife.
One Line Solution:
@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); }
More Readable Solution:
@OnClick(R.id.activity_signup_layout)
public void closeKeyboard() {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
Explanation: Bind OnClick Listener to the activity's XML Layout parent ID, so that any click on the layout (not on the edit text or keyboard) will run that snippet of code which will hide the keyboard.
Example: If your layout file is R.layout.my_layout and your layout id is R.id.my_layout_id, then your Butterknife bind call should look like:
(@OnClick(R.id.my_layout_id)
public void yourMethod {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
Butterknife Documentation Link: http://jakewharton.github.io/butterknife/
Plug: Butterknife will revolutionize your android development. Consider it.
Maybe a little bit easier:
Set a focusChangedListener on your edit text and then just hide the keyboard if you don't have focus.
yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
hideKeyboard();
}
}
});
private void hideKeyboard() {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0);
}