将调用 Fragment 使用的 ViewModel 共享给 viewModels 使用的 DialogFragment
Share ViewModel used by calling Fragment to DialogFragment using by viewModels
我有一个 SearchFragment
,代码如下。
@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")
}
...
}
我正在使用 SearchFragment
显示 FilterBottomSheetDialogFragment
。我想将 SearchFragment
的 ViewModel 传递给 DialogFragment
。我的 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 = ???
}
我试过了
private val viewmodel by viewModels<SearchViewModel>(ownerProducer = { this.requireParentFragment() })
上面的方法不起作用,因为它只是创建了一个新的 ViewModel 实例。
我也试过了
private val viewmodel: SearchViewModel by lazy {
ViewModelProvider(requireParentFragment()).get(SearchViewModel::class.java)
}
上面的错误提示无法创建 SearchViewModel
实例。我的 SearchViewModel
有这个构造函数。
@HiltViewModel
class SearchViewModel @Inject constructor(
private val courseRepository: CourseRepository
) : ViewModel()
如何在不使用构造函数参数的情况下将 SearchViewModel
传递给 DialogFragment
?
你错了,实际上是你在显示对话框时使用的片段管理器。目前您正在使用 parent 片段管理器,而您的对话框应该作为显示它的片段的子片段存在。
所以你应该使用:
dialog.show(childFragmentManager, "filter_bsd_tag")
这将确保
viewModels<SearchViewModel>(ownerProducer = { requireParentFragment() })
指的是SearchFragment
.
我有一个 SearchFragment
,代码如下。
@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")
}
...
}
我正在使用 SearchFragment
显示 FilterBottomSheetDialogFragment
。我想将 SearchFragment
的 ViewModel 传递给 DialogFragment
。我的 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 = ???
}
我试过了
private val viewmodel by viewModels<SearchViewModel>(ownerProducer = { this.requireParentFragment() })
上面的方法不起作用,因为它只是创建了一个新的 ViewModel 实例。
我也试过了
private val viewmodel: SearchViewModel by lazy {
ViewModelProvider(requireParentFragment()).get(SearchViewModel::class.java)
}
上面的错误提示无法创建 SearchViewModel
实例。我的 SearchViewModel
有这个构造函数。
@HiltViewModel
class SearchViewModel @Inject constructor(
private val courseRepository: CourseRepository
) : ViewModel()
如何在不使用构造函数参数的情况下将 SearchViewModel
传递给 DialogFragment
?
你错了,实际上是你在显示对话框时使用的片段管理器。目前您正在使用 parent 片段管理器,而您的对话框应该作为显示它的片段的子片段存在。
所以你应该使用:
dialog.show(childFragmentManager, "filter_bsd_tag")
这将确保
viewModels<SearchViewModel>(ownerProducer = { requireParentFragment() })
指的是SearchFragment
.