I have a SearchFragment
with the following code.
@AndroidEntryPoint
class SearchFragment :
Fragment(),
View.OnClickListener {
...
private var _binding: FragSearchBinding? = null
private val binding get() = _binding as FragSearchBinding
private val viewmodel by viewModels<SearchViewModel>()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
)
: View {
_binding = FragSearchBinding.inflate(inflater, container, false)
binding.fragSearchSearchResultFilter.setOnClickListener(this)
return binding.root
}
...
private fun showFilterDialog() {
val dialog = FilterBottomSheetDialogFragment.newInstance()
dialog.show(parentFragmentManager, "filter_bsd_tag")
}
...
}
I am showing a FilterBottomSheetDialogFragment
using that SearchFragment
. I want to pass the ViewModel of SearchFragment
to the DialogFragment
. I have this code for my FilterBottomSheetDialogFragment
.
@AndroidEntryPoint
class FilterBottomSheetDialogFragment :
BottomSheetDialogFragment(),
View.OnClickListener {
companion object {
fun newInstance() = FilterBottomSheetDialogFragment()
private const val TAG_SELECTION_DIALOG = "tag_selection_dialog"
}
private var _binding: BsdFilterBinding? = null
private val binding get() = _binding as BsdFilterBinding
private val viewmodel: SearchViewModel = ???
}
I have tried
private val viewmodel by viewModels<SearchViewModel>(ownerProducer = { this.requireParentFragment() })
The above doesn't work as it just creates a new instance of ViewModel.
I also tried
private val viewmodel: SearchViewModel by lazy {
ViewModelProvider(requireParentFragment()).get(SearchViewModel::class.java)
}
The above doesn't work with the error saying that the SearchViewModel
instance cannot be created. My SearchViewModel
has this constructor.
@HiltViewModel
class SearchViewModel @Inject constructor(
private val courseRepository: CourseRepository
) : ViewModel()
How can I pass the SearchViewModel
to the DialogFragment
without using the constructor parameter?
You're mistake here is actually the fragment manager you're using when showing your dialog. Currently you're using the parent fragment manager, whereas your dialog should exist as a child fragment of the fragment it is being shown from.
So you should be using:
dialog.show(childFragmentManager, "filter_bsd_tag")
which will then ensure that
viewModels<SearchViewModel>(ownerProducer = { requireParentFragment() })
refers to the SearchFragment
.