相关文章推荐
重情义的青椒  ·  解决 class ...·  1 周前    · 
逼格高的土豆  ·  java.lang.IllegalAcces ...·  1 周前    · 
愤怒的伤疤  ·  mybatis foreach ...·  1 年前    · 
痴情的键盘  ·  c# - ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to implement data-binding in android with kotlin:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mBinding = DataBindingUtil.inflate<ViewDataBinding>(
            inflater, R.layout.fragment_login, container, false
        ) as FragmentLoginBinding
        val view: View = mBinding.root
        mBinding.login?.invoke(viewModel)
        return view

But it says lateinit property viewModel has not been initialized on runtime. How can I resolve this ?

  • Initializing in fragment will work
  • It will better if you guys provide me with viewmodel initialized from parent, parent is an activity
  • If You want to init viewModel in Activity and use it in fragment You can do it in this way:

    MainActvity.kt:

    private lateinit var viewModel: MainActivityVM
    override fun onCreate(savedInstanceState: Bundle?)
        viewModel = ViewModelProvider(this).get(MainActivityVM::class.java)
        super.onCreate(savedInstanceState)
    

    YourFragment.kt:

    private lateinit var binding: YourFragmentBinding
    private lateinit var viewModel: MainActivityVM
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View?
        binding = DataBindingUtil.inflate(
            inflater,
            R.layout.fragment_your, container, false
        binding.lifecycleOwner = this
        viewModel = ViewModelProvider(requireActivity()).get(MainActivityVM::class.java)
        //here You can use Your viewModel
        return binding.root
    

    lateinit properties require you to initialize them before the first use. The error happens only if it wasn't initialized. You can check if lateinit is initialized by using isInitialized property of KProperty0 interface.

    val isReadyForUse = ::viewModel.isInitialized
    

    Inside of a Fragment you can initialize a ViewModel using extension function viewModels():

    import androidx.fragment.app.viewModels
    class YourFragment: Fragment {
        private val viewModel: YourViewModel by viewModels()
    

    It's lazy-loaded, which means as soon as you'll try to access viewModel it will be initialized and returned. Next time no initialization will happen.

    If you want to make your ViewModel class loaded in an Activity first and later in a Fragment use activityViewModels().

    Note: after the first initialization of a ViewModel by activityViewModels() it will be stored in a ViewModelStore that is owned by Activity. To create new instance of a YourViewModel by using activityViewModels() you will have to finish your Activity or clear view model store requireActivity().viewModelStore.clear().

    To initialize in an Activity and use a Fragment do next:

    class YourActivity {
        override fun onCreate(savedInstanceState: Bundle?) {
            val viewModelInit = ViewModelProvider(this).get(YourViewModel.javaClass)
    

    And in a Fragment:

    import androidx.fragment.app.activityViewModels
    class YourFragment: Fragment {
        private val viewModel: YourViewModel by activityViewModels()
    

    Here is the thing worked for me :

    mBinding = DataBindingUtil.inflate<ViewDataBinding>(
                inflater, R.layout.fragment_login, container, false
            ) as FragmentLoginBinding
            val view: View = mBinding.root
            viewModel = ViewModelProvider(requireActivity()).get(AuthViewModel::class.java)
            mBinding.login = viewModel
            return view
    

    In XML :

    <?xml version="1.0" encoding="utf-8"?>
    <layout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools">
            <variable
                name="login"
                type="com........." />
        </data>
            

    Thanks for contributing an answer to Stack Overflow!

    • Please be sure to answer the question. Provide details and share your research!

    But avoid

    • Asking for help, clarification, or responding to other answers.
    • Making statements based on opinion; back them up with references or personal experience.

    To learn more, see our tips on writing great answers.