DialogFragment UI 在关闭后仍然存在

Posted

技术标签:

【中文标题】DialogFragment UI 在关闭后仍然存在【英文标题】:DialogFragment UI still remains after dismiss 【发布时间】:2021-04-13 15:53:53 【问题描述】:

我有一个自定义对话框片段,我面临的问题是,当调用解除函数时,即使它实际上被解除,对话框 UI 仍然保留在屏幕上。 onDismiss 函数也被调用,但 UI 仍然位于父 Fragment 上。

这是我的对话类

class IAPDialogFragment : DaggerDialogFragment() 
// Listener
var onSuccessfulIAP: (IAPDialogFragment.() -> Unit)? = null

override fun getTheme(): Int = R.style.DialogTheme

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? =
    inflater.inflate(R.layout.iap_dialog, container, false)

override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
    super.onViewCreated(view, savedInstanceState)
    iap_dialog?.applyOutlineCornerRadius(30)

    setState(state, errorReason)
    action_button.setOnClickListener 
        dismiss()
    


override fun onDismiss(dialog: DialogInterface) 
    super.onDismiss(dialog)
    if (this.state == State.SUCCESS) 
        onSuccessfulIAP?.invoke(this)
    


fun setState(state: State, errorReason: IapException? = null) = apply 
    this.state = state
    this.errorReason = errorReason

    when (state) 
        State.LOADING -> 
            isCancelable = false
            action_button?.visibility = View.GONE
        
        State.SUCCESS -> 
            isCancelable = true
            action_button?.visibility = View.VISIBLE
            iap_dialog?.setBackgroundResource(R.drawable.iap_card_success_background)
        
        State.ERROR -> 
            isCancelable = true
            action_button?.visibility = View.VISIBLE
        
    

这是父片段:

class IAPFragment : DaggerFragment()
private val dialog = IAPDialogFragment()

override fun onActivityCreated(savedInstanceState: Bundle?) 
    super.onActivityCreated(savedInstanceState)

    billingViewModel.state.observe(viewLifecycleOwner)  state ->
        when (state) 
            State.OFFERS_LOADING -> showLoadingState()
            State.OFFERS_LOADING_FAILED -> showEmptyState()
            State.OFFERS_LOADED -> showOffers(billingViewModel.skuList)
            State.PURCHASING -> dialog.setState(LOADING)
            State.PURCHASING_SUCCESS -> dialog.setState(SUCCESS)
            State.PURCHASING_FAILED -> dialog.setState(ERROR, billingViewModel.errorReason)
            else -> showEmptyState()
        
    


private fun updateButton(position: Int) 
    subscribe_button.apply 
        setOnClickListener 
            dialog.setState(LOADING)
            dialog.show(childFragmentManager, LOADING.name)
        
    

我做错了什么吗? DialogFragment被解除后,有没有办法刷新UI状态?

【问题讨论】:

在 onDismiss 函数中将超级命令移动到 if 语句下方并运行。希望有效。 不,不走运。非常有趣的是,在调用dismiss之后,手机挂了,当我关闭应用程序时,那个冻结的对话框UI将被设置为设备的壁纸!! 【参考方案1】:

经过数小时的调查,我终于发现样式中的动画是问题所在。显然,DaggerDialogFragments 与android:windowAnimationStyle 存在兼容性问题。 我使用的风格是:

<style name="DialogTheme" parent="AppTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowAnimationStyle">@style/DialogAnimation</item>
</style>

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/fragment_fade_enter</item>
    <item name="android:windowExitAnimation">@anim/fragment_fade_exit</item>
</style>

我改成:

<style name="DialogTheme" parent="AppTheme">
    <item name="android:windowNoTitle">true</item>
    <item name="android:windowIsFloating">false</item>
    <item name="android:windowIsTranslucent">true</item>
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowContentOverlay">@null</item>
    <item name="android:backgroundDimEnabled">false</item>
    <item name="android:windowEnterAnimation">@anim/fragment_fade_enter</item>
    <item name="android:windowExitAnimation">@anim/fragment_fade_exit</item>
</style>

它神奇地解决了这个问题!

【讨论】:

我在升级到最新的片段版本到最新的 1.4.0-alpha06 时也遇到了这个问题 我们不使用 DaggerDialogFragments,只使用普通的 DialogFragments

以上是关于DialogFragment UI 在关闭后仍然存在的主要内容,如果未能解决你的问题,请参考以下文章

试图将数据从 DialogFragment 传递回父 Activity

当用户单击关闭按钮关闭 DialogFragment 时出现 IllegalStateException

关闭 DialogFragment 时出现 NullPointerException

Recycler View 和 DialogFragment 苦苦挣扎(Kotlin)

java 如果您想让DialogFragment具有嵌入能力,则必须在布局中定义对话框的UI,然后在onCreateView()回调中加载布局。

java 如果您想让DialogFragment具有嵌入能力,则必须在布局中定义对话框的UI,然后在onCreateView()回调中加载布局。