With ChatSheetFragment()
, a brand new fragment is getting created and therefore a brand new ViewModel
in case that you bind this ViewModel
to that fragment.
This can be solved by binding that ChatSheetFragment
to the parent activity/fragment ViewModel
that can host the updated list.
So, in short:
Change the ViewModel
in the ChatSheetFragment
to either the parent fragment/activity (according to your desgin):
i.e., instead of ViewModelProvider(this)[MyChatViewModel::class.java]
you'd replace this
with requireParentFragment()
or requireActivity()
and replace MyChatViewModel
with the one of the parent fragment/activity.
Move the list logic that you want to maintain from the chat fragment ViewModel
to the parent ViewModel
.
Another solution is not to create a brand new fragment with ChatSheetFragment()
and just show the existing one; but not sure if that can affect the performance to keep it alive while you don't need it.
Edit:
problem to me is bottomsheetfragment is detaching and destroying itself whenever it dismiss. what can i do so that it can not be destroyed
This is right; calling dismiss()
or even setting the BottomSheetBehavior state to STATE_HIDDEN
will destroy the fragment.
But there is a workaround to just hide the decorView of the dialogFragment window whenever you want to hide the chat fragment like the following:
val chatDialogFragment = ChatSheetFragment()
// Hide the bottom sheet dialog fragment
chatDialogFragment.dialog.hide(); // equivalent to dialog.window.decorView.visiblity = View.GONE
// Show the bottom sheet dialog fragment
chatDialogFragment.dialog.show // equivalent to dialog.window.decorView.visiblity = View.VISIBLE
But you need to handle the situations when the DialogFragment can hide; here is a couple ones:
Customize the dialog in onCreateDialog()
:
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return object : BottomSheetDialog(requireContext(), theme) {
override fun onBackPressed() {
this@BottomSheetFragment.dialog?.hide()
}
}
}
- Dismiss on touch outside:
@SuppressLint("ClickableViewAccessibility")
override fun onStart() {
super.onStart()
val outsideView =
requireDialog().findViewById<View>(com.google.android.material.R.id.touch_outside)
isCancelable = false
dialog?.setCanceledOnTouchOutside(false)
outsideView.setOnTouchListener { _: View?, event: MotionEvent ->
if (event.action == MotionEvent.ACTION_UP) dialog?.hide()
false
}
Whenever you want to show the fragment again; just show its dialog without re-instantiating it as described above