如何正确关闭DialogFragment?解决dismiss背景空白、onBackPressed退App问题
DialogFragment关闭异常解决方案
问题表现
尝试两种方案关闭DialogFragment均失败:
- 第一种方案调用
dismiss()关闭,弹窗消失后底层页面完全空白,代码如下:
binding.closeBtn.setOnClickListener { dismiss() }
- 第二种方案调用Activity返回方法关闭,触发后整个应用直接退出,代码如下:
close_btn.setOnClickListener { requireActivity().onBackPressed() }
原有完整实现代码
class CongratulationsDialog : DialogFragment() { lateinit var bid :String lateinit var sharedPreference: SharedPreference var mLogoProgressDialog: ProgressDialog? = null var text : String = "" var uid :String = "" override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { val binding = DataBindingUtil.inflate<CongratulationsDialogBinding>( inflater, R.layout.congratulations_dialog, container, false) dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) dialog?.setContentView(R.layout.congratulations_dialog) dialog?.window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT) sharedPreference = activity?.let { SharedPreference(it) }!! bid = sharedPreference.getValueString("sendBid").toString() text = sharedPreference.getValueString("token").toString() uid = sharedPreference.getValueString("login_uid").toString() Log.d("checkLoginId",""+uid+"Bid"+bid) initializeLogoProgressDialog() loadBettingStatus(bid,text,binding) binding.closeBtn.setOnClickListener { dismiss() } binding.createNewBoastButton.setOnClickListener { view?.let { it1 -> Navigation.findNavController(it1) .navigate(R.id.action_congratulationsDialog_to_newBoastFragment) } } return binding.root } private fun initializeLogoProgressDialog() { if (mLogoProgressDialog == null) { Log.w("PBFX", "initializeLogoProgressDialog called - mLogoProgressDialog = NULL") } else { Log.w("PBFX", "initializeLogoProgressDialog called - mLogoProgressDialog NOT NULL") } if (mLogoProgressDialog == null) { dismissLogoProgressDialog() mLogoProgressDialog = ProgressDialog(requireContext()) mLogoProgressDialog!!.show() mLogoProgressDialog!!.setCancelable(false) mLogoProgressDialog!!.getWindow()!! .setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) mLogoProgressDialog!!.setContentView(R.layout.progress_bar) } } private fun loadBettingStatus(bid: String, text: String, binding: CongratulationsDialogBinding) { val apiInterface = RetrofitService.api.getInviteesDetails(bid,"Bearer "+text) apiInterface.enqueue( object : Callback<Invitees> { override fun onResponse(call: Call<Invitees>?, response: Response<Invitees>) { if (response.isSuccessful) { dismissLogoProgressDialog() if (response?.body() != null) { if(response.body()!!.data.status.equals("completed")) { binding.textView7.text =response.body()!!.data.name if (uid.equals(response.body()!!.data.betWinner.uid)) { binding.youTxt.setText("You") if(response.body()!!.data.mode.equals("task")){ binding.textView10.setText(response.body()!!.data.taskTitle) }else{ binding.textView10.setText("$"+response.body()!!.data.value) } } else { dismissLogoProgressDialog() binding.youTxt.setText(response.body()!!.data.betWinner.name) if(response.body()!!.data.mode.equals("task")){ binding.textView10.setText(response.body()!!.data.taskTitle) }else{ binding.textView10.setText("$"+response.body()!!.data.value) } } } } }else{ dismissLogoProgressDialog() } } override fun onFailure(call: Call<Invitees>?, t: Throwable?) { if (t != null) { dismissLogoProgressDialog() Log.d("gettingFailure",""+t.message) } } }) } private fun dismissLogoProgressDialog() { if (mLogoProgressDialog != null) { mLogoProgressDialog!!.dismiss() } mLogoProgressDialog = null } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // close_btn.setOnClickListener { // requireActivity().onBackPressed() // } } override fun getTheme() = R.style.RoundedCornersDialog }
问题根因
- 视图逻辑混用:
onCreateView中已经通过DataBinding加载了布局并返回根视图,同时又手动调用dialog?.setContentView()重复设置布局,导致Dialog的视图层级混乱,dismiss时触发异常渲染。 - 导航逻辑错误:你使用了Navigation组件管理页面跳转,DialogFragment作为导航栈中的目的地,直接调用
dismiss()不会更新导航栈状态,导致返回后页面空白;直接调用Activity的onBackPressed()会直接回退整个Activity的栈,当前栈只有一个目的地时就会直接退出应用。
修复步骤
- 删除
onCreateView中重复配置Dialog的三行代码:
// 移除以下三行 dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE) dialog?.setContentView(R.layout.congratulations_dialog) dialog?.window?.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT)
- 替换关闭按钮的点击逻辑,使用Navigation的回栈方法关闭弹窗:
binding.closeBtn.setOnClickListener { findNavController().popBackStack() }
- (可选)如果需要调整Dialog的宽高样式,重写
onStart方法配置:
override fun onStart() { super.onStart() dialog?.window?.apply { setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT) setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) } }
内容的提问来源于stack exchange,提问作者Jaanu
相关产品推荐
相关产品推荐

