0

My goal is to allow only one single instance of the same dialog fragment in the fragment stack.

The current trigger condition is coming from a SharedFlow and can be triggered as often as 7ms apart between values.

Here's what I have tried:

  1. Placing the code in a synchronized block
  2. Checking whether existing fragment is in the stack by calling fm.findFragmentByTag

However, both the conditions are not enough to prevent the fragment from adding multiple times to the fragmentManager.

I tried with dialogFragment.showNow(fm, tag) but it's unstable and it's crashing

Appreciate for any helps.


override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
  viewModel.someSharedFlow
    .flowWithLifecycle(viewLifecycleOwner.lifecycle)
    .onEach { showMyFragmentDialog() }
    .launchIn(viewLifecycleOwner.lifecycleScope)
}

private fun showMyFragmentDialog() {
  synchronized(childFragmentManager) {
    if (childFragmentManager.findFragmentByTag(MyFragment.TAG) == null) {
      MyFragment.newInstance(fuelTypes)
        .show(childFragmentManager, MyFragment.TAG)
    }
  }
}

You Qi
  • 8,353
  • 8
  • 50
  • 68

1 Answers1

0

Resorted with coroutine for now. Not ideal but at least it's working.

private var myLaunchJob: Job? = null
private fun showMyFragmentDialog() {
  if (myLaunchJob?.isActive == true) return
  myLaunchJob = viewLifecycleOwner.lifecycleScope.launch {
    if (childFragmentManager.findFragmentByTag(MyFragment.TAG) == null) {
      MyFragment.newInstance(fuelTypes)
        .show(childFragmentManager, MyFragment.TAG)
    }
    // Act as debouncer
    delay(1000)
  }
}
You Qi
  • 8,353
  • 8
  • 50
  • 68