首页 > 解决方案 > onOptionsItemSelected 访问 dataBinding viewModel

问题描述

如何让 onOptionsItemSelected 方法上的 dataBinding viewModel 可访问。

class TestFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        // viewModel

        val viewModelFactory = TestViewModelFactory(
            ...
        )
        val viewModel = ViewModelProvider(
            this, viewModelFactory).get(TestViewModel::class.java)

        // dataBinding

        val binding = FragmentTestBinding.inflate(inflater)
        binding.lifecycleOwner = this
        binding.viewModel = viewModel

        return binding.root
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when(item.itemId) {
            R.id.test_menu_item -> {
                this.findNavController().navigate(
                    TestFragmentDirections
                        .actionTestFragmentToAnotherTestFragment(
                            ...
                        )
                )
                viewModel.onNavigated() // How to access the viewModel here
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

标签: androidandroid-databindingandroid-navigation

解决方案


好的,声明整个班级都可以访问的 lateinit 全局变量

private lateinit var viewModel : TestViewModel

现在用 onCreate() 中的工厂初始化 viewModel:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // factory
        val viewModelFactory = TestViewModelFactory()
        // viewModel
        viewModel = ViewModelProvider(this, viewModelFactory).get(TestViewModel::class.java)
    }

所以整个代码看起来像:

class TestFragment : Fragment() {

    private lateinit var viewModel : TestViewModel

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // factory
        val viewModelFactory = TestViewModelFactory()
        // viewModel
        viewModel = ViewModelProvider(this, viewModelFactory).get(TestViewModel::class.java)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        // dataBinding
        val binding = FragmentTestBinding.inflate(inflater)
        binding.lifecycleOwner = this
        binding.viewModel = viewModel

        return binding.root
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        return when(item.itemId) {
            R.id.test_menu_item -> {
                this.findNavController().navigate(
                    TestFragmentDirections.actionTestFragmentToAnotherTestFragment()
                )
                viewModel.onNavigated() // How to access the viewModel here
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }
}

推荐阅读