How to properly use FragmentResultListener with a Dialog

Viewed 1930

I have a fragment that starts a DialogFragment with a DatePickerDialog. I want to pass the date back to the host fragment. I saw someone use setTargetFragment but that is deprecated and on the docs for that function it said to use setFragmentResultListener, but the FragmentResultListener.onFragmentResult function seems to not get called.

What am I doing wrong and what is good convention?

Host Fragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    childFragmentManager.setFragmentResultListener(
        REQUEST_DATE,
        viewLifecycleOwner,
        this
    )
}

override fun onFragmentResult(requestKey: String, result: Bundle) {
    Log.d(TAG, "Key: $requestKey, Bundle: $result")
}

Dialog:

val requestKey = requireArguments().getString(
    ARG_REQUEST_KEY,
    ""
)

val bundle = Bundle().apply {
    putSerializable(requestKey, resultDate)
}

requireParentFragment().setFragmentResult(
    requestKey,
    bundle
)

Also, I am passing the host fragment's childFragmentManager when calling the DialogFragment.show function.

2 Answers

You don't want to call requireParentFragment().setFragmentResult - that's setting the result in the parent Fragment's FragmentManager. Instead, you just want to call setFragmentResult() directly on your Fragment as per the documentation:

val requestKey = requireArguments().getString(
    ARG_REQUEST_KEY,
    ""
)

val bundle = Bundle().apply {
    putSerializable(requestKey, resultDate)
}

setFragmentResult(
    requestKey,
    bundle
)

You can pass lambda function to your dialog fragment constructer. When you want to pass this data to HostFragment you can call this function.

class MyDialog(
    private val backData: (String) -> Unit
): DialogFragment() {
    override fun onDestroy() {
        super.onDestroy()
        backData("Send your data")
    }
}

I call this method in onDestroy method but you can cal anywhere. Also you can pass your custom data instead of String

in your host fragment

private fun setupDialog() {
    MyDialog { data ->
        // Do your thing
        Toast.makeText(context, "$data", Toast.LENGTH_SHORT).show()
    }.show(supportFragmentManager, "my_dialog")
}

I do not know is this you looking for but i hope this can help you.

Related