android隐藏dialog,Android:Dialog中隐藏键盘的注意事项

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

如今我们做一个自己定义的Dialog

MyDialog extends Dialog一開始觉得这个功能非常easy实现,于是写了以下的代码

//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
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值