1

I have created one chatsheetfragment(Bottomsheetdialogfragment). Whenever I open it I'm calling all the chats and binding in RecyclerView. So, my problem is the chat sheet is always reloading from onCreate() which eventually results refreshing the fragment every time. how to stop it.

And I'm using viewmodel using dagger-hilt . Viewmodel instance is also creating every time.

Tried opening as singleton instance but not worked and now I'm opening like below

 private fun chatButton() {
    binding.chatIv.setOnClickListener {
        ChatSheetFragment().show(
            supportFragmentManager,
            ChatSheetFragment::class.java.simpleName
        )
    }
 }
Zain
  • 37,492
  • 7
  • 60
  • 84
Syed Ibrahim
  • 356
  • 2
  • 6

1 Answers1

1

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:

  • Dismiss on back press

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

Zain
  • 37,492
  • 7
  • 60
  • 84
  • Hi actually i have implemented this one but problem to me is bottomsheetfragment is detaching and destroying itself whenever it dismiss. what can i do so that it can not be destroyed – Syed Ibrahim Feb 02 '23 at 06:47
  • You're right; not sure if you can hide the dialogFragment without destroying it; I will try to test that out. for now you can go for the parent ViewModel. – Zain Feb 02 '23 at 07:03
  • Ok thanks that will be helpful for community – Syed Ibrahim Feb 02 '23 at 07:30
  • 1
    @SyedIbrahim Just updated the answer; but for me I'd go for the SharedViewModel described above. – Zain Feb 02 '23 at 08:41
  • 1
    There is an issue on using `onBackPressedDispatcher` in dialogFragment as per [this](https://stackoverflow.com/questions/57160036/dialogfragment-ignores-onbackpresseddispatcher) post – Zain Feb 02 '23 at 08:44
  • Zain you have any idea like iam subscribing to channel events from view model , iam getting some inconsistencies there like one event is invoking in fragment while other event is not invoking, as there is not at all difference in two events only names changed. – Syed Ibrahim Feb 02 '23 at 09:48
  • Can you open a question for this so that a one can check the code and see – Zain Feb 02 '23 at 10:04
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/251562/discussion-between-syed-ibrahim-and-zain). – Syed Ibrahim Feb 02 '23 at 10:19