AlertDialog中EditText软键盘自动弹出与隐藏
好久没动安卓原生开发,都快忘的差不多了。
项目有个需求是在弹出的 AlertDialog 中输入一些文字,这就牵扯到软键盘的自动弹出与隐藏了。虽然以前也做过,但时间久了有些生疏,还是费了些时间。所以记录下来便于以后翻阅。
效果图:
点开之后自动弹出有延时,这个时间是自己设的,设多长时间根据情况而定。
具体实现
关键点说明:
- 这句代码解决软键盘不能弹出的问题。如果不加这句,软键盘不会弹出。
alertDialog.setView(LayoutInflater.from(context).inflate(R.layout.widget_ip_config, null));
-
alertDialog.show()
一定要在alertDialog.getWindow().setContentView(view)
之前调用,否则 AlertDialog 不会弹出。 - 这里自动弹出软键盘用了延迟加载的方法,建个计时器等200毫秒之后再弹出。因为Dialog渲染或初始化需要一定时间,在渲染完成之前软键盘是弹不出来的。等待的时间根据自己喜好来设置,但不能太短,亲测100毫秒的话有时不能成功弹出,200毫秒比较保险。
- 隐藏软键盘的时机是通过
setOnDismissListener()
监听了onDismiss()
方法,在此方法执行隐藏软键盘的操作。
下面贴代码:
先建一个封装的工具类IpConfigWidget.java
public class IpConfigWidget {
@Inject
public IpConfigWidget() {
}
public void showIpConfigDialog(Context context) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
AlertDialog alertDialog = builder.create();
//解决无法弹出软键盘的bug
alertDialog.setView(LayoutInflater.from(context).inflate(R.layout.widget_ip_config, null));
alertDialog.show();
View view = LayoutInflater.from(context).inflate(R.layout.widget_ip_config, null);
//输入ip地址的EditText框
EditText etIpAddress = view.findViewById(R.id.et_ip_address);
//自动获取焦点并弹出软键盘
showSoftInput(etIpAddress);
//确定按钮
view.findViewById(R.id.tv_confirm_dialog).setOnClickListener((v) -> {
String ip = etIpAddress.getText().toString().trim();
onButtonClickListener.onConfirmBtnClick(alertDialog, ip);
});
//取消按钮
view.findViewById(R.id.tv_cancel_dialog).setOnClickListener((v) -> {
onButtonClickListener.onCancelBtnClick(alertDialog);
});
//为AlertDialog设置View
alertDialog.getWindow().setContentView(view);
//监听Dialog Dismiss时隐藏软键盘
alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
//隐藏软键盘
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
}
});
}
/**
* 自动获取焦点并弹出软键盘
* @param etIpAddress
*/
private void showSoftInput(EditText etIpAddress) {
//自动获取焦点
etIpAddress.setFocusable(true);
etIpAddress.setFocusableInTouchMode(true);
etIpAddress.requestFocus();
//200毫秒后弹出软键盘
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
InputMethodManager inputManager = (InputMethodManager) etIpAddress.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.showSoftInput(etIpAddress, 0);
}
}, 200);
}
/**
* 对外暴露确定取消按钮点击接口
*/
private OnButtonClickListener onButtonClickListener;
public interface OnButtonClickListener {
void onConfirmBtnClick(AlertDialog dialog, String ip);
void onCancelBtnClick(AlertDialog dialog);
}
public void setOnButtonClickListener(OnButtonClickListener onButtonClickListener) {
this.onButtonClickListener = onButtonClickListener;
}
}
布局文件 widget_ip_config.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/confirm_dialog_bg"
android:layout_centerInParent="true"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:minHeight="80dp"
android:gravity="center_vertical"
>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:text="IP地址:http://"
android:textColor="@color/gray676165"
android:textSize="16sp"
/>
<EditText
android:id="@+id/et_ip_address"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginLeft="5dp"
android:textColor="@color/black"
android:hint="输入ip地址"
android:background="@null"
android:focusable="true"
android:focusableInTouchMode="true"
android:inputType="text"
/>
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/divider_color" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal"
>
<TextView
android:id="@+id/tv_cancel_dialog"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:padding="5dp"
android:text="取消"
android:textColor="@color/gray676165"
android:textSize="16sp"
android:background="@drawable/selector_dialog_btn_cancel"
/>
<TextView
android:layout_width="1dp"
android:layout_height="match_parent"
android:background="@color/divider_color" />
<TextView
android:id="@+id/tv_confirm_dialog"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:padding="5dp"
android:text="保存"
android:textColor="@color/blue"
android:textSize="16sp"
android:background="@drawable/selector_dialog_btn_confirm"
/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
调用方法:
IpConfigWidget ipConfigWidget = new IpConfigWidget();
ipConfigWidget.showIpConfigDialog(LoginActivity.this);
ipConfigWidget.setOnButtonClickListener(new IpConfigWidget.OnButtonClickListener() {
@Override
public void onConfirmBtnClick(AlertDialog dialog, String ip) {
//自己的逻辑代码
dialog.dismiss();
}
@Override
public void onCancelBtnClick(AlertDialog dialog) {
dialog.dismiss();
}
});