android键盘关闭按钮,Android 开发之Dialog中隐藏键盘的正确使用方法

Android 开发之Dialog中隐藏键盘的正确使用方法

场景:弹出一个Dialog,里面有一个EditText,用来输入内容,因为输入时,需要弹出键盘,所以当Dialog消失时,键盘要一起隐藏。

现在我们做一个自定义的Dialog

MyDialog extends Dialog

一开始认为这个功能很容易实现,于是写了下面的代码

//Dialog的构造函数中写

this.setOnDismissListener(new OnDismissListener() {

@Override

public void onDismiss(DialogInterface dialog) {

hideKeyBoard();

}

});

//edContent是输入框

public void hideKeyBoard(){

InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);

inputMethodManager.hideSoftInputFromWindow(edContent.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

}

运行之后,发现根本无法隐藏,看看hideSoftInputFromWindow中干了啥

public boolean hideSoftInputFromWindow(IBinder windowToken, int flags,

ResultReceiver resultReceiver) {

checkFocus();

synchronized (mH) {

if (mServedView == null || mServedView.getWindowToken() != windowToken) {

return false;

}

try {

return mService.hideSoftInput(mClient, flags, resultReceiver);

} catch (RemoteException e) {

}

return false;

}

}

跟踪进去发现参数 windowToken 是 null,而且 mServedView 也是null,所以直接返回false,无法隐藏。

也就是说,你监听Cancel或者Dismiss都是不行的,因为此时Dialog已经消失,用于输入的服务窗体已经是null了,所以你要想 隐藏键盘,就需要在Dismiss之前处理,那这个入口在哪呢?

为了当点击空白处时,可以隐藏Dialog,所以我们在构造函数中加了一句话

this.setCanceledOnTouchOutside(true);

所以当我们点击空白区域时,会触发Dialog的onTouchEvent

public boolean onTouchEvent(MotionEvent event) {

if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {

cancel();

return true;

}

return false;

}

这里会调用基类Window的shouldCloseOnTouch方法,来判断是否可以关闭,这里我们看到如果满足,就直接cancel()了,

public void cancel() {

if (!mCanceled && mCancelMessage != null) {

mCanceled = true;

// Obtain a new message so this dialog can be re-used

Message.obtain(mCancelMessage).sendToTarget();

}

dismiss();

}

这里面就会dismiss掉Dialog,所以我们发现,在dismiss前,我们根本无法干预,真是个悲剧。所以我们只能重载onTouchEvent方法,并且自己判断是否可以关闭(也就是把下面代码迁移到你的代码中!

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {

if (mCloseOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN

&& isOutOfBounds(context, event) && peekDecorView() != null) {

return true;

}

return false;

}

private boolean isOutOfBounds(Context context, MotionEvent event) {

final int x = (int) event.getX();

final int y = (int) event.getY();

final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();

final View decorView = getDecorView();

return (x < -slop) || (y < -slop)

|| (x > (decorView.getWidth()+slop))

|| (y > (decorView.getHeight()+slop));

}

自己代码中这样

@Override

public boolean onTouchEvent(MotionEvent event) {

if (isShowing() && shouldCloseOnTouch(getContext(),event)){

hideKeyBoard();

}

return super.onTouchEvent(event);

}

public boolean shouldCloseOnTouch(Context context, MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN

&& isOutOfBounds(context, event) && getWindow().peekDecorView() != null) {

return true;

}

return false;

}

private boolean isOutOfBounds(Context context, MotionEvent event) {

final int x = (int) event.getX();

final int y = (int) event.getY();

final int slop = ViewConfiguration.get(context).getScaledWindowTouchSlop();

final View decorView = getWindow().getDecorView();

return (x < -slop) || (y < -slop)

|| (x > (decorView.getWidth()+slop))

|| (y > (decorView.getHeight()+slop));

}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidDialog关闭键盘需要以下步骤: 1. 首先,获取Dialog的Window对象。可以通过`dialog.getWindow()`方法来实现。 2. 接下来,调用Window的`setSoftInputMode()`方法,将其参数设置为`WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN`。这将会使得软键盘始终不会自动弹出。 3. 最后,调用Window的`setContentView()`方法加载布局文件或者视图对象。 代码示例: ```java Dialog dialog = new Dialog(context); Window window = dialog.getWindow(); window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); window.setContentView(R.layout.dialog_layout); ``` 在AndroidDialog控制软键盘的显示与隐藏,可以通过以下方式实现: 1. 如果Dialog有EditText控件需要获取焦点时,可以使用`InputMethodManager`类来显示软键盘。可以在控件获得焦点时,调用`InputMethodManager`的`showSoftInput()`方法来显示软键盘。 代码示例: ```java EditText editText = dialog.findViewById(R.id.edit_text); editText.requestFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); ``` 2. 如果需要在特定情况下隐藏键盘,可以使用`InputMethodManager`类的`hideSoftInputFromWindow()`方法。 例如,当失去焦点或者点击Dialog外部区域时,可以调用`hideSoftInputFromWindow()`方法隐藏键盘。 代码示例: ```java View rootView = dialog.findViewById(R.id.root_view); rootView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(view.getWindowToken(), 0); } return false; } }); ``` 通过以上步骤,可以在AndroidDialog关闭键盘以及控制软键盘的显示与隐藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值