Search code examples
androidkotlindialogfragmentfragmentmanager

Activity calling a DialogFragment: Dialog does not always get dismissed


I have an Activity that calls a DialogFragment like this:

private fun showDeleteDetailDialog(itemView: View, categoryId: String, detailId: String) {
    val dialog = DeleteDetailDialogFragment.newInstance(categoryId, detailId)
    dialog.show([email protected], "DeleteDetailDialog")
}

And this is the code for my DialogFragment (a click on the PositiveButton deletes an item in Firebase database):

class DeleteDetailDialogFragment : DialogFragment() {

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    // Use the Builder class for convenient dialog construction
    val categoryId = arguments.getString(ARG_CATEGORY_ID)
    val detailId = arguments.getString(ARG_DETAIL_ID)
    val builder = AlertDialog.Builder(activity)
    builder.setMessage(R.string.delete_detail)
            .setPositiveButton(R.string.delete, { dialog, id ->
                deleteDetail(categoryId, detailId)
            })
            .setNegativeButton(R.string.cancel, { dialog, id ->
                // User cancelled the dialog
            })
    // Create the AlertDialog object and return it
    return builder.create()
}

private fun deleteDetail(categoryId: String, detailId: String) {
    // get the detail reference for the specified category
    val deleteRef = FirebaseDatabase.getInstance().getReference("details").child(categoryId).child(detailId)
    // remove detail
    deleteRef.removeValue()

    // get the reference for the specified favorite, identified by detailId
    val deleteFaveRef = FirebaseDatabase.getInstance().getReference("favorites").child(detailId)
    // remove favorite
    deleteFaveRef.removeValue()
}

companion object {
    private val ARG_CATEGORY_ID = "category_id"
    private val ARG_DETAIL_ID = "detail_id"

    fun newInstance(categoryId: String, detailId: String): DeleteDetailDialogFragment {
        val fragment = DeleteDetailDialogFragment()
        val args = Bundle()
        args.putString(ARG_CATEGORY_ID, categoryId)
        args.putString(ARG_DETAIL_ID, detailId)
        fragment.arguments = args
        return fragment
    }
}
}

When I call the Dialog, the Dialog window pops up. When I then click Cancel (the NegativeButton) the Dialog disappears as expected. When I click Delete (the PositiveButton), the Dialog disappears, again as expected.

BUT, after a successful Delete, when I call the Dialog again, a click on Cancel does not immediately dismiss the dialog; instead, the Dialog box pops up again and only disappears after a second click on Delete. There seems to be an issue with the FragmentManager. What am I missing here?


Solution

  • There's nothing wrong with the code above! Removing an item in Firebase database triggered an onDataChange event in my ValueEventListener which then called an updateUI function. Unfortunately, I had my onItemTouchListener handling onItemClick events (like my remove() instruction via DialogFragment) placed there, which worked fine as long as I didn't change any data in my Firebase database. But removing an item there triggered a loop that caused the "erratic" behavior of my code. The solution was to move the call to my onItemTouchListener (that handles onItemClicks) from the updateUI function to the onCreate section of my code. Huh, I learnt something!