I have a Fragment that opens a DialogFragment with some settings in it. When I change the settings in the DialogFragment I want the underlying Fragment to collect the changes. I use a view model and StateFlows to store the settings and have collectors set up in the Fragment, however, they are never called. But the view model is updated correctly. Is it because of the viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED)
that the collectors are not called because the DialogFragment is showing? But the background fragment is still active.
When I use MutableLiveData
instead of MutableStateFlow
and make an observer instead of the collector, it works, too. So it must be something within the coroutine.
class SomeFragment : Fragment() {
// Dropped the other functions, e.g. onCreate, for simplicity
val settings by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.testButton.setOnClickListener {
val settingsFragment = SettingsDialogFragment()
settingsFragment.show(requireActivity().supportFragmentManager, "settings")
}
lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
settings.lowerState.collect {
Log.e("DEBUG", "lowerState switched")
}
settings.upperState.collect {
Log.e("DEBUG", "upperState switched")
}
}
}
}
}
class SettingsViewModel(application: Application) : AndroidViewModel(application) {
val lowerState: MutableStateFlow<Boolean> = MutableStateFlow(true)
val upperState: MutableStateFlow<Boolean> = MutableStateFlow(true)
}
The dialog fragment is a simple dialog with no special functions
class SettingsDialogFragment : DialogFragment() {
private var _binding: FragmentSettingsDialogBinding? = null
private val binding get() = _binding!!
private val settings: SettingsViewModel by activityViewModels()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
_binding = FragmentRecordingSettingsDialogBinding.inflate(
layoutInflater,
null,
false
)
_binding!!.settings = settings
val builder = AlertDialog.Builder(requireActivity())
return builder.setView(binding.root).create()
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="settings"
type="com.example.SettingsViewModel"/>
</data>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.appcompat.widget.SwitchCompat
android:checked="@={settings.upperState}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<androidx.appcompat.widget.SwitchCompat
android:checked="@={settings.lowerState}"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
from Change of StateFlow not collected by Fragment when done in DialogFragment
No comments:
Post a Comment