我有大约 15 个片段,大部分使用相同的代码,我还为 ViewBinding 创建了一个有效的 BaseFragment,这样我就不需要每次都编写该部分。 然而,还有其他函数在所有片段上重复,但它们利用每个片段的视图(在所有片段上都是相同的),但我一生都找不到如何正确引用它们或在 BaseFragment 中设置它们.
这是我当前的 BaseFragment:
abstract class BaseFragment<VB : ViewBinding> : Fragment() {
private var _binding: VB? = null
val binding: VB
get() = _binding!!
abstract fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?,
attachToRoot: Boolean
): VB
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = inflateBinding(inflater, container, false)
return binding.root
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
fun navigateToActivity(activityClass: Class<*>) {
val intent = Intent(requireContext(), activityClass)
startActivity(intent)
requireActivity().finish()
}
}
这是我想重新利用的每个片段上存在的功能之一:
private fun navButtons() {
binding.btnExit.setOnClickListener {
val currentTime = System.currentTimeMillis()
if (currentTime - lastExitButtonClickTime < 2000) {
navigateToActivity(IntroTreasurehuntersActivity::class.java)
} else {
Toast.makeText(context, "Press again to exit", Toast.LENGTH_SHORT).show()
lastExitButtonClickTime = currentTime
}
}
}
以防万一,这就是我对它们进行视图绑定的方式,我很确定这也可以更好:
class Treasurehuntersq2Fragment : BaseFragment<FragmentTreasurehuntersq2Binding>() {
override fun inflateBinding(
inflater: LayoutInflater,
container: ViewGroup?,
attachToRoot: Boolean
): FragmentTreasurehuntersq2Binding {
return FragmentTreasurehuntersq2Binding.inflate(inflater, container, attachToRoot)
}
现在,如果我简单地将该函数复制到 BaseFragment,当然它不起作用,因为那里不存在视图按钮“btnExit”。正确的做法是什么?
对于ViewBinding Part,你可以在baseFragment中声明一个受保护的绑定属性,并让每个childFragment对其进行初始化。
为了处理导航事件,您可以考虑在所有片段之间使用 SharedViewModel,这样任何事件都会从片段发送到 viewModel,并从 BaseFragment 观察这些事件并相应地处理它们,这是一个示例解决方案。
abstract class BaseFragment<VB : ViewBinding> : Fragment() {
protected lateinit var binding: VB
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
observeNavigationState()
}
private fun observeNavigationState(){
viewModel.NavigateToIntroTreasurehuntersActivity.observe(viewLifecycleOwner) { NavigateToIntroTreasurehuntersState -> ->
if (NavigateToIntroTreasurehuntersState) { // true i.e naviagtion is started
val intent = Intent(
requireActivity(),
IntroTreasurehuntersActivity::class.java
)
startActivity(intent)
requireActivity().finish()
viewModel.onNavigateToIntroTreasurehuntersActivityFinished()
}
}
}
}
类 Treasurehuntersq2Fragment:BaseFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentTreasurehuntersq2Binding.inflate(inflater)
return binding.root
}
override fun onViewCreated(
view: View,
savedInstanceState: Bundle?
) {
setListeners()
}
private fun setListeners(){
binding.btnExit.setOnClickListener {
val currentTime = System.currentTimeMillis()
if (currentTime - lastExitButtonClickTime < 2000) {
viewModel.onNavigateToIntroTreasurehuntersActivityStarted()
} else {
Toast.makeText(context, "Press again to exit", Toast.LENGTH_SHORT).show()
lastExitButtonClickTime = currentTime
}
}
}
}