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
I use below Process. It's Working For Me Perfectly. Add below function in your activity Class.
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN) {
val v = currentFocus
if (v is EditText) {
val outRect = Rect()
v.getGlobalVisibleRect(outRect)
if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
Log.d("focus", "touchevent")
v.clearFocus()
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(v.windowToken, 0)
}
}
}
return super.dispatchTouchEvent(event)
}
Then I will Check Focus status in my fragment.
appCompatEditText.onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
if (!hasFocus) {
toast("Focus Off")
}else {
toast("Focus On")
}
}
I was Checked in Fragment. I needed Focus status for my task Requirement. Focus Out I needed some task.
This way, the keyboard will only disappear when you touch a view that can gain focus. I suggest you to do the following:
Create a custom ViewGroup like this:
public class TouchLayout extends LinearLayout {
private OnInterceptTouchEventListener mListener;
public TouchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if(mListener != null) {
return mListener.onInterceptTouchEvent(event);
}
return super.onInterceptTouchEvent(event);
}
public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener listener) {
mListener = listener;
}
public interface OnInterceptTouchEventListener {
public boolean onInterceptTouchEvent(MotionEvent event);
}
}
Then add the custom View as a root of your xml layout:
<com.example.TouchLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<EditText
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
And in your Activity you should do the following:
final TouchLayout root = (TouchLayout) findViewById(R.id.root);
final EditText text = (EditText) findViewById(R.id.text);
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
root.setOnInterceptTouchEventListener(new OnInterceptTouchEventListener() {
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
final View v = getCurrentFocus();
if(v != null && v.equals(text)) {
final int screenCords[] = new int[2];
text.getLocationOnScreen(screenCords);
final Rect textRect = new Rect(screenCords[0], screenCords[1], screenCords[0] + text.getWidth(), screenCords[1] + text.getHeight());
if(!textRect.contains(event.getRawX(), event.getRawY() {
imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0);
// Optionally you can also do the following:
text.setCursorVisible(false);
text.clearFocus();
}
}
return false;
}
};
In Kotlin, I have used bellow code which is working fine
override fun dispatchTouchEvent(ev: MotionEvent): Boolean {
val v = currentFocus
if (v != null && (ev.action == MotionEvent.ACTION_UP || ev.action == MotionEvent.ACTION_MOVE)
&& v is EditText
&& !v.javaClass.name.startsWith("android.webkit.")
) {
val scrcoords = IntArray(2)
v.getLocationOnScreen(scrcoords)
val x = ev.rawX + v.getLeft() - scrcoords[0]
val y = ev.rawY + v.getTop() - scrcoords[1]
if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom()
) hideKeyboard(this)
}
return super.dispatchTouchEvent(ev)
}
fun hideKeyboard(activity: Activity?) {
if (activity != null && activity.window != null && activity.window.decorView != null
) {
val imm = activity
.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(
activity.window.decorView
.windowToken, 0
)
}
}
In Java, I have used bellow code which is working fine
@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 scrcoords[] = new int[2];
v.getLocationOnScreen(scrcoords);
float x = ev.getRawX() + v.getLeft() - scrcoords[0];
float y = ev.getRawY() + v.getTop() - scrcoords[1];
if (x < v.getLeft() || x > v.getRight() || y < v.getTop()
|| y > v.getBottom())
hideKeyboard(this);
}
return super.dispatchTouchEvent(ev);
}
public static void hideKeyboard(Activity activity) {
if (activity != null && activity.getWindow() != null
&& activity.getWindow().getDecorView() != null) {
InputMethodManager imm = (InputMethodManager) activity
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(activity.getWindow().getDecorView()
.getWindowToken(), 0);
}
}