Android 如何监听输入法软键盘关闭事件

时间:2021-12-14 23:40:48

假设有如下界面(输入法的上面的输入区域是用Dialog实现的)

Android 如何监听输入法软键盘关闭事件

要求当输入法关闭的时候,Dialog也一起关闭,这样用户就不需要返回两次了。

网上找了很多资料都没有很好的解决这个问题,输入法是第三方程序,确实不好检测它的关闭与显示。

后来在EditText源码中看到


public boolean onKeyPreIme(int keyCode, KeyEvent event){

}

对该方法官方文档:

Handle a key event before it is processed by any input method associated with the view hierarchy. This can be used to intercept key events in special situations before the IME consumes them; a typical example would be handling the BACK key to update the application’s UI instead of allowing the IME to see it and close itself.

特别是最后一句话,该方法可以用来处理返回键来更新程序的UI。

一、使用onKeyPreIme()方法来实现

所以我们监听通过 onKeyPreIme 的返回键,来关闭Dialog。


public class MyEditText extends EditText {

public MyEditText(Context context) {
super(context);
}

public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}

public interface BackListener {
void back(TextView textView);
}



private BackListener listener;

public void setBackListener(BackListener listener) {
this.listener = listener;
}



@Override

public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
if (listener != null) {
listener.back(this);
}
}
return false;
}
}


在布局中使用我们自定义的EditText来代替系统的EditText:


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical">




<LinearLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center_vertical"
android:orientation="horizontal">


<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="长"
android:textColor="#333"
android:textSize="14sp"/>




<MyEditText
android:id="@+id/et_length"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@null"
android:gravity="center"
android:hint="0cm"
android:inputType="number"
android:maxLines="5"
android:textColorHint="#ccc"/>

</LinearLayout>



<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/divider_line"/>




<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="宽
android:textColor="
#333"
android:textSize="14sp"/>


<MyEditText
android:id="@+id/et_width"
android:layout_width="match_parent"
android:layout_height="wrap_content
android:layout_marginLeft="
10dp"
android:background="@null"
android:gravity="center"
android:hint="0cm"
android:inputType="number"
android:maxLines="5"
android:textColorHint="#ccc"/>

</LinearLayout>
</LinearLayout>



<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_line"/>




<LinearLayout
android:layout_width="match_parent"
android:layout_height="44dp"
android:gravity="center_vertical"
android:orientation="horizontal">




<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal">




<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="高"
android:textColor="#333"
android:textSize="14sp"/>




<MyEditText
android:id="@+id/et_height"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:background="@null"
android:gravity="center"
android:hint="0cm"
android:inputType="number"
android:maxLines="5"
android:textColorHint="#ccc"/>

</LinearLayout>



<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/divider_line"/>




<View
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal"/>


</LinearLayout>
</LinearLayout>

然后在Activity实现该接口,并且调用back方法


@Override

public void back(TextView textView) {
if (sizeDialog != null && sizeDialog.isShowing()) {
sizeDialog.dismiss();
}
}

private void initViews(){
MyEditText etLength = (MyEditText) sizeDialog.findViewById(R.id.et_length);
etLength.setBackListener(this);
MyEditText etWidth = (MyEditText) sizeDialog.findViewById(R.id.et_width);
etWidth.setBackListener(this);
MyEditText etHeight = (MyEditText) sizeDialog.findViewById(R.id.et_height);
etHeight.setBackListener(this);
}

二、使用setOnKeyListener()方法来实现

如果不想新建一个EditText的子类,可以使用EditText的setOnKeyListener()方法,如:

editText.setOnKeyListener(new View.OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_UP) && (keyCode == KeyEvent.KEYCODE_BACK)) {
Logger.d("editTextvalue:" + editText.getText());
return true;
}
return false;
}
});

该方式和onKeyPreIme的方式有点区别,EditText输入完数值后,按返回键,setOnKeyListener回调只会调用一次(action=ACTION_UP),而onKeyPreIme的回调会调用两次(action=ACTION_DOWN和action=ACTION_UP)。但是当用户继续按返回键关闭界面时,onKeyPreIme和setOnKeyListener的方式的回调方法都会调用两次(action=ACTION_DOWN和action=ACTION_UP)。

最后运行效果,按返回键,键盘和Dialog都消失了:

Android 如何监听输入法软键盘关闭事件