Android项目移除Kotlin extension后自定义Dialog视图操作失效问题
问题原因
你的代码对同一个布局文件R.layout.custom_dialog执行了两次完全独立的inflate操作,生成了两个互不关联的视图实例:
- 第一次通过View Binding生成
bindingDialogLayout,你对etTitle设隐藏、给etDetail设初始值、后续读取输入都是操作这个实例里的控件 - 第二次通过
layoutInflater.inflate()生成dialogLayout,你最终把这个实例设置给了AlertDialog作为展示视图
两个视图实例完全独立,你操作的控件根本不在最终展示的对话框视图上,自然所有修改和读取都不会生效。
修复方案
删掉冗余的单独inflate代码,直接把Binding绑定的根视图设置给对话框即可,修改后的代码如下:
private lateinit var bindingDialogLayout: CustomDialogBinding fun specialRequestDialog(currentRequest: String?) { // 仅需通过View Binding inflate一次布局即可 bindingDialogLayout = CustomDialogBinding.inflate(layoutInflater) val etTitle = bindingDialogLayout.etTitle val etDetail = bindingDialogLayout.etDetails etTitle.visibility = View.GONE etDetail.setText(currentRequest) MaterialAlertDialogBuilder(this) .setTitle("What is your special request?") .setCancelable(false) .setPositiveButton("Save") { dialog, which -> val newRequest = etDetail.text.toString() if (newRequest.isEmpty()) { showErrorSnackBar("Type in if you have any special request, else hit cancel", true) } else { addButton.visibility = View.GONE deleteButton.visibility = View.VISIBLE } } .setNegativeButton("Cancel") { dialog, which -> dialog?.dismiss() } // 直接传入Binding绑定的根视图作为对话框内容 .setView(bindingDialogLayout.root) .show() }
额外优化建议
- 不需要把
bindingDialogLayout声明为类的成员变量,直接在方法内作为局部变量即可,可降低内存泄漏风险 - 如果在Fragment中使用该方法,inflate Binding时需要传入对应的LifecycleOwner
内容的提问来源于stack exchange,提问作者Codist
相关产品推荐
相关产品推荐

