1

I have this code inside onCreate inside an activity:

        week_info.setOnClickListener { v ->
        ChangeWeekDialogFragment.newInstance(weekPagerAdapter.displayedWeek) { week ->
            week_view_pager.currentItem += week.weeksBetween(weekPagerAdapter.displayedWeek)
        }.show(supportFragmentManager, "ChangeWeekDialogFragment")
    }

The lambda passed into the newInstance function executes when a new week is set inside the ChangeWeekDialogFragment.

The problem is that whenever there's an orientation change while the ChangeWeekDialogFragment is shown and then I change the week, it's as if the line inside the lambda expression wasn't called because the ViewPager doesn't change its displayed item. What's strange though, is that the line week_view_pager.currentItem += week.weeksBetween(weekPagerAdapter.displayedWeek) actually gets called when I set a breakpoint on it.

With no orientation change while the ChangeWeekDialogFragment is opened, everything works as you'd expect.

Thank you!

Matt
  • 123
  • 1
  • 12

1 Answers1

1

Since view is detroyed when orientation changed your dialog view is recreated and so lose any listener added to it. You need to add back listener when you activity/fragment container start

override fun onStart()
{
    super.onStart()
    
    val fragment = fragmentManager.findFragmentByTag("tag")
    fragment?.addListener...
}

This is a quick fix but a better implementation is to use targetFragment from Fragment class which serve the purpose to send data back to the caller if it's a fragment. When creating your dialog fill dialog targetFragment with your fragment caller instance, then when you're done with your dialog (when you click ok for example) from your dialog call

targetFragment.onActivityResult(0 , Activity.RESULT_OK, yourData)

then from your fragment call override onActivityResult

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
{
    week_view_pager.currentItem += week.weeksBetween(weekPagerAdapter.displayedWeek)
}

Doing this way you don't have to care about state lost/orientation change/etc... everything works as expected and it looks cleaner than checking if your dialog has been restored from onStart method.

RonU
  • 5,525
  • 3
  • 16
  • 13
Samuel Eminet
  • 4,647
  • 2
  • 18
  • 32
  • 1
    You could also require your "target fragment" to implement whatever arbitrary interface you want and just enforce that requirement in `onCreate` / `onAttach` / etc. That being said, the target fragment API is being deprecated and Google is encouraging the use of the "Fragment Result API". For more details, see https://stackoverflow.com/questions/64869501/how-to-replace-settargetfragment-now-that-it-is-deprecated – Brian Yencho May 19 '21 at 18:10