Search code examples
androidandroid-dialogfragmentdialogfragment

DialogFragment UI still remains after dismiss


I have a custom dialog fragment, the issue I am facing is that when the dismiss function is called, the dialog UI still remains on the screen even tho it's actually dismissed. The onDismiss function is also called but the UI still sits on the parent fragment.

This is my dialog class

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
        }
    }
}

And this is the parent fragment:

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)
        }
    }
}

Is there anything I am doing wrong? Is there any solution to refresh the UI state after the DialogFragment is dismissed?


Solution

  • After many hours of investigation, I finally found the Animation in the Style was the issue. Apparently, DaggerDialogFragments have a compatibility issue with android:windowAnimationStyle. The style I was using was:

    <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>
    

    I changed it to:

    <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>
    

    And it magically solved the issue!