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