在使用AlertDialog的时候,经常会遇到这样的需求:点击【确认】之后,如果dialog内的输入内容有误,则dialog不dismiss。但实际情况是,无论点击【确认】还是【取消】,dialog都会执行dismiss操作。

查看源码如下:

View.OnClickListener mButtonHandler = new View.OnClickListener() {  public void onClick(View v) {  Message m = null;  if (v == mButtonPositive && mButtonPositiveMessage != null){  m = Message.obtain(mButtonPositiveMessage);  } else if (v == mButtonNegative && mButtonNegativeMessage != null) {  m = Message.obtain(mButtonNegativeMessage);  } else if (v == mButtonNeutral && mButtonNeutralMessage != null) {  m = Message.obtain(mButtonNeutralMessage);  }  if (m != null) {  m.sendToTarget();  }  // Post a message so we dismiss after the above handlers are executed  mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, mDialogInterface).sendToTarget();  }  };  

上面的源码为AlertController中自定义的button点击监听事件,从代码中可以看到,点击按钮一共执行了两次handler的send操作,一次是按钮的点击send:m.sendToTarget(),执行按钮的点击事件,紧接着又执行了一条handler的send操作:mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG, mDialogInterface).sendToTarget();操作。因此我们得到,不论你点击dialog的哪个按钮,最后都会执行dialog的dismiss操作。

因此,基于上面的需求,我们需要修改点击事件的执行过程。通过查找资料,一共找到两种方式解决这一问题:

方法一:使用自定义的按钮,不使用dialog的setNegativeButton和setPositiveButton,并为自定义的按钮添加点击事件,在自定义的按钮点击监听事件中,对dialog的dismiss进行管理;

方法二:更多时候,我们的dialog实现一个很简单的功能,并不用大费周章的自定义一个button。所以我们可以使用反射的方式来实现上面的需求,具体实现代码如下:

 final EditText et = new EditText(mContext);et.setInputType(InputType.TYPE_CLASS_NUMBER);et.setText(PreferenceUtil.getInstance().getDefaultInt(ConstValue.TEST_DATA_LENGTH, 2000) + "");et.setTextColor(mContext.getResources().getColor(R.color.color_black));TextView tv = new TextView(mContext);tv.setText("Title测试");tv.setTextColor(mContext.getResources().getColor(R.color.red_normal));tv.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 25);new AlertDialog.Builder(mContext).setCustomTitle(tv).setView(et).setPositiveButton("确定", new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int which) {String input = et.getText().toString();if (StringUtil.isEmpty(input)) { // 不满足条件式时,提示,并不dismiss该dialogCommonUtil.customToast(mContext, "数据包长度不能为空", Toast.LENGTH_SHORT, Gravity.TOP);try {Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");field.setAccessible(true);field.set(dialog, false);} catch (Exception e) {e.printStackTrace();}} else {int length = Integer.valueOf(input);if (length < 500) {CommonUtil.customToast(mContext, "数据包长度至少500", Toast.LENGTH_SHORT, Gravity.TOP);try {Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");field.setAccessible(true);field.set(dialog, false);} catch (Exception e) {e.printStackTrace();}} else { // 满足条件式时,使该dialog
可以dismiss                                PreferenceUtil.getInstance().persist(ConstValue.TEST_DATA_LENGTH, length);try {Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");field.setAccessible(true);field.set(dialog, true);} catch (Exception e) {e.printStackTrace();}}}}}).setNegativeButton("取消", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {try {Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing");field.setAccessible(true);field.set(dialog, true);} catch (Exception e) {e.printStackTrace();}}}).show();

这样就可以实现我们上面的需求了。

注:在开始实现反射这样的方法时,报了这样的错误:

java.lang.NoSuchFieldException: No field mShowing in class Landroid/support/v7/app/AppCompatDialog; (declaration of 'android.support.v7.app.AppCompatDialog' appears in /data/app/com.rencarehealth.mirhythm-1/split_lib_dependencies_apk.apk:classes19.dex)

从错误描述可知,mShowing名字的field并不存在AppCompatDialog的class中,所以需要将你代码中引入的Dialog类修改为非support_v7中的Dialog。

Dialog确认按钮不dismiss相关推荐

  1. 修改vant 弹窗Dialog组件调用是确认按钮与取消按钮的文字

    文章目录 修改vant 弹窗Dialog组件调用是确认按钮与取消按钮的文字 效果图 · 示例: 重要代码如下(部分): 代码使用 · 注意事项: 官方文档参数定义 · 注意事项: 文章阅读: 修改va ...

  2. Dialog确认框重复提交的问题

    require(['dialog/0.4.0/dialog'], function (UIDialog) { var dialog = new UIDialog(); $(".demo1&q ...

  3. bootstrap 单选按钮点击change事件 只触发一次_微信支付新增“确认”按钮,付错钱将成为历史?...

    阅读本文之前,麻烦您先点击上面蓝色字体"蓝色字体",再点"关注",这样您就可以继续"免费"收到文章了,每天都有分享,完全是"免费订 ...

  4. 如何调换antd中Modal对话框确认按钮和取消按钮两个按钮的位置

    今天有个工作是把所有的确认按钮放在取消按钮的左边,类似于下图这样的,公司用的时antd组件 但是antd组件的按钮时确认键放在右边的 可以采用下面的方式,将按钮调换过来: 对的,就是在modal里面的 ...

  5. android 支付选择按钮,微信支付新增“确认”按钮,更安全还是更麻烦?

    近日,安卓版微信悄悄更新了版本,在最新的V7.0.5版本中,微信支付的付款界面和步骤发生了变化. 据移动支付网了解,此次微信支付更新之后,个人转账过程中,会弹出微信自带的安全键盘,而且输入金额时会有相 ...

  6. 小程序中的confirm-type设置键盘的确认按钮

    详情: confirm-type是很多小程序组件中的一种设置,用于改变输入键盘右下角的确认按钮.比如说,正常情况下,键盘上的默认提示可能是完成,但是你可以通过confirm-type将其设置为发送,搜 ...

  7. elementUI二次确认按钮

    开发中需要用到二次确认按钮,防止误触等操作. 原代码为: el-button @click="changeBtn()">修改</el-button> (修改函数已 ...

  8. 标题Ant Design of Vue 组件库中Modal“确认“按钮和“取消“按钮成英文状态

    标题Ant Design of Vue 组件库中Modal"确认"按钮和"取消"按钮成英文状态 因为是国际化的原因,造成确定按钮和取消按钮变成英文,需要设置 o ...

  9. 小程序中confirm-type设置键盘的确认按钮

    介绍 confirm-type是很多小程序组件中的一种设置,用于改变输入键盘右下角的确认按钮.比如说,正常情况下,键盘上的默认提示可能是完成,但是你可以通过confirm-type将其设置为发送,搜索 ...

  10. oauth最后的确认按钮_绕过GitHub的OAuth授权验证机制($25000)

    这几年来,信息安全研究一直是我的业余爱好,虽然有很多人专职做漏洞众测以获得奖励,但对我个人来说,我只对一些感兴趣的项目投入不多的时间去深入研究.今年,我想看看自己是否是全职漏洞赏金猎人的料,所以就从6 ...

最新文章

  1. 网络流最大流EK算法板子
  2. iphone 使用ZBar 条码扫描
  3. linux 父子进程的关系
  4. BZOJ3577 : 玩手机
  5. Python处理图像五个有趣场景,很实用!
  6. 搭建云计算机win10,win10电脑做云服务器
  7. ST 电机库 电机位置环7天冲刺开发
  8. springboot简单集成quartz定时任务框架,实现用户封号定时解封问题
  9. Win7-64位系统安装vs2003
  10. ubuntu和win7共享文件
  11. neutron的dvr
  12. Unity免费资源汇总
  13. 三角形中重心、内心、外心、垂心向量计算公式
  14. udc分类号查询 计算机技术,论文的分类号和udc_udc_论文分类号查询系统
  15. PhpSpreadsheet读取excel
  16. CF终于上紫了。。。
  17. 如何使用iMacros自动化重复的网页浏览器任务
  18. 区间最值操作与历史最值问题(一)
  19. 机器人开发--丝杠与导轨
  20. 华为一碰传如何安装,支持多屏协同,电脑控制手机等

热门文章

  1. 今年能不能回家全靠这3个抢票工具了|2022版
  2. kettle 学习笔记
  3. 在计算机中汉字能否排序,你不得不知的Excel表格中汉字多种排序方法
  4. 【Android 】零基础到飞升 | ListView简单实用
  5. Unbuntu22.04安装教程以及Unbuntu下C++环境的配置
  6. android 如何读取u盘中数据恢复,U盘数据恢复常见问题及恢复方法汇总
  7. Python写的我的世界源码
  8. 2021年北京市级企业技术中心申报时间及流程是什么,补贴300万
  9. 红米K30升级鸿蒙系统,Redmi K30 Pro变焦版相机免费升级,DxOMark版本马上到
  10. 许三多的 “职业精神”