I need to hide the softkeypad in android when user click on anywhere other than a Edittext. There are many help for iphone but not for android. I tried this code but its not working :(
final RelativeLayout base = (RelativeLayout) findViewById(R.id.RelativeLayout1);
findViewById(R.id.base).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(base.getWindowToken(), 0);
}
});
Thanks in advance !
You can use the onTouchEvent()
to hide the Softkeyboard
.
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
Though this solution works, but the best I would suggest is to use below answer as it gives best solution of closing the keyboard touching anywhere else then EditText.
Well I have done this way:
Add code in your Activity.
This would work for Fragment also, no need to add this code in Fragment.
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
View view = getCurrentFocus();
if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
int scrcoords[] = new int[2];
view.getLocationOnScreen(scrcoords);
float x = ev.getRawX() + view.getLeft() - scrcoords[0];
float y = ev.getRawY() + view.getTop() - scrcoords[1];
if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
}
return super.dispatchTouchEvent(ev);
}
Hope this will help you.
The best work around I found was using as below,
Override dispatchTouchEvent()
and try to get the area of EditText
using Rect
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();
if (ev.getAction() == MotionEvent.ACTION_DOWN &&
!getLocationOnScreen(etFeedback).contains(x, y)) {
InputMethodManager input = (InputMethodManager)
activity.getSystemService(Context.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(etFeedback.getWindowToken(), 0);
}
return super.dispatchTouchEvent(ev);
}
Method that caculates 4 corner of View(here its EditText)
protected Rect getLocationOnScreen(EditText mEditText) {
Rect mRect = new Rect();
int[] location = new int[2];
mEditText.getLocationOnScreen(location);
mRect.left = location[0];
mRect.top = location[1];
mRect.right = location[0] + mEditText.getWidth();
mRect.bottom = location[1] + mEditText.getHeight();
return mRect;
}
By using above code we can detect the area of EditText
and we can check if the touch on the screen is part of the area of EditText
or not. If its part of EditText
then don't do anything let the touch do its job, and if the touch doesn't contain area of EditText
then just close the softkeyboard.
******EDIT******
I just found another approach if we don't want to give any EditText as input and want to hide keyboard inside whole application when user touches anywhere else other than EditText. Then you have to create an BaseActivity and write global code for hiding keyboard as below,
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
boolean handleReturn = super.dispatchTouchEvent(ev);
View view = getCurrentFocus();
int x = (int) ev.getX();
int y = (int) ev.getY();
if(view instanceof EditText){
View innerView = getCurrentFocus();
if (ev.getAction() == MotionEvent.ACTION_UP &&
!getLocationOnScreen(innerView).contains(x, y)) {
InputMethodManager input = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(getWindow().getCurrentFocus()
.getWindowToken(), 0);
}
}
return handleReturn;
}
I tried this to hide Keyboard. You need to pass the method in your Layout file.
public void setupUI(View view) {
// Set up touch listener for non-text box views to hide keyboard.
if (!(view instanceof EditText)) {
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
hideSoftKeyboard(LOGSignUpActivity.this);
return false;
}
});
}
//If a layout container, iterate over children and seed recursion.
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
View innerView = ((ViewGroup) view).getChildAt(i);
setupUI(innerView);
}
}
}
Call this method in your MainAcitivity.class
public static void hideKeyboardwithoutPopulate(BaseActivity activity) {
InputMethodManager inputMethodManager =
(InputMethodManager) activity.getSystemService(
Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
activity.getCurrentFocus().getWindowToken(), 0);
}
For those who are looking for a Xamarin code for this, here you go :
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);
}