【问题标题】:onClick with dataBinding an ViewModel doesn't workonClick 与 dataBinding 一个 ViewModel 不起作用
【发布时间】:2020-01-16 08:28:05
【问题描述】:

我正在开发一个项目并使用databindingnavigation 实现MVVM 模型。 My buttonfragment 上,以drawer menu item 打开,问题是当我单击按钮时它什么也不做,调试器没有进入导航方法,我真的不知道我做了什么错了,谁能帮忙?

MYACCOUNT CLASS:

class MyAccountFragment : BaseFragment() {

    private val vm: MyAccountViewModel by viewModel()


    override fun getViewModel(): BaseViewModel = vm

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding = FragmentMyAccountBinding.inflate(inflater, container, false)
        context ?: return binding.root
        injectFeature()

        setToolbar(binding)
        subscribeUi(binding)

        return binding.root
    }

    /**
     * set toolbar
     * **/
    private fun setToolbar(binding: FragmentMyAccountBinding) {

        binding.appBarLayout.backClickListener = (activity as MainActivity).createOnBackClickListener()
    }

    /**
     * set ui
     * **/
    private fun subscribeUi(binding: FragmentMyAccountBinding) {
        binding.viewModel = vm
    }


}

MYACCVIEWMODEL


class MyAccountViewModel constructor() : BaseViewModel() {

    fun onAddRoomClick()
    {
        navigate(MyAccountFragmentDirections.actionMyAccountFragmentToAddRoomFragment())
    }
}

在xml中我实现了

android:onClick="@{() -> viewModel.onAddRoomClick()}"

我对我所有的FragmentsViewModels 都使用这种模式,我真的不知道为什么它什么都不做,vm 初始化了。在另一个 drawermenu fragment 我也有 onClick 方法,它导航到另一个片段。因此,如果有人知道会有所帮助的解决方案,请提前感谢您。

【问题讨论】:

    标签: android kotlin onclick


    【解决方案1】:

    答案在 viewModel 的初始化中。

    xml 中的 onClick 方法位于包含在 fragment_layout 中的 content_layout 中,而不是 binding.viewModel = vm 我不得不做 binding.content_layout.viewModel = vm。

     private fun subscribeUi(binding: FragmentMyAccountBinding) {
            binding.contentMyAccount.viewModel = vm
        }
    

    【讨论】:

      【解决方案2】:

      ViewModel 不应该处理任何类型的导航,它只会从 UI 接收事件并将其传递给控制器​​(可能是片段或活动),后者将处理导航...

      所以解决问题的一种方法是执行以下操作:

      视图模型

         class MyAccountViewModel constructor() : BaseViewModel() {
      private val _navigateToRoomFragEvent = MutableLiveData<Boolean>(false)
      val navigateToRoomFragEvent:LiveData<Boolean>
          get()=_navigateToRoomFragEvent
      
      fun onAddRoomClick()
      {
          _navigateToRoomFragEvent.value=true
      }
      fun resetNavigation(){
          _navigateToRoomFragEvent.value=false
      }
      

      }

      控制器(Activity 或 Fragment)

      内部**onCreate()(如果是活动)**

      viewModel.navigateToRoomFragEvent.observe(this,Observer{navigate->
      //boolean value
      if(navigate){
      navController.navigate(//action)
      }
      viewModel.resetNavigation() //don't forget to reset the event
      })
      

      onActivityCreated(如果是片段)

      viewModel.navigateToRoomFragEvent.observe(viewLifeCycleOwner,Observer{navigate->
      //boolean value
      if(navigate){
      navController.navigate(//action)
      }
      viewModel.resetNavigation() //don't forget to reset the event
      })
      

      希望对你有帮助,

      【讨论】:

      • 你没有真正回答 Tin 的问题。他真的在问为什么不调用他的 onClick 回调(不是为什么他的导航不起作用)。此外,您的陈述“ViewModel 不应该处理任何类型的导航”是不正确的。让视图模型直接从绑定的 XML 按钮接收按钮单击,然后通过 LiveData 向片段发出导航事件(如您在示例中所示)没有任何问题。
      猜你喜欢
      • 1970-01-01
      • 2014-08-08
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2015-02-24
      • 2019-02-21
      • 2014-03-31
      • 1970-01-01
      相关资源
      最近更新 更多