Kotlin 中的接收器类型与 Android 的“activityViewModels”不匹配

receiver type mismatch in Kotlin with Android's `activityViewModels`

多年未接触 Android,而且根本不是真正的 Kotlin。我的 Fragment 有其中之一:

package com.example.my_frag

import androidx.lifecycle.ViewModel
import androidx.fragment.app.activityViewModels
import com.example.MainViewModel


class MyFragViewModel : ViewModel() {
    private val viewModel: MainViewModel by activityViewModels<MainViewModel>()
}

为了完成,这里是 Fragment:

package com.example.my_frag

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ListView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import com.example.R


class MyFragment : Fragment() {
    private lateinit var myFragViewModel: MyFragViewModel

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        myFragViewModel =
                ViewModelProvider(this).get(MyFragViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_my, container, false)
        return root
    }
}

…我的 Activity 看起来像:

package com.example

import android.os.Bundle
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer


class MainActivity : AppCompatActivity() {
    private val viewModel: MainViewModel by viewModels<MainViewModel>()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        viewModel.selectedItem.observe(this, Observer { item ->
            println("$item observed")
        })
    }
}

ViewModel 为:

package com.example

import android.view.MenuItem
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel


class MainViewModel : ViewModel() {
    private val mutableSelectedItem = MutableLiveData<MenuItem>()
    val selectedItem: LiveData<MenuItem> get() = mutableSelectedItem

    fun selectItem(item: MenuItem) {
        mutableSelectedItem.value = item
    }
}

我小心地将这些 dependencies 添加到我的 build.gradle:

dependencies {
    implementation "android.arch.lifecycle:extensions:1.1.1"
    implementation "androidx.fragment:fragment-ktx:1.2.5"
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.3.2'
    implementation 'androidx.navigation:navigation-ui-ktx:2.3.2'
    implementation 'androidx.vectordrawable:vectordrawable:1.1.0'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'com.google.android.material:material:1.2.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

但是它不起作用,activityViewModels 突出显示为红色,错误是:

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: public inline fun <reified VM : ViewModel> Fragment.activityViewModels(noinline factoryProducer: (() -> ViewModelProvider.Factory)? = ...): Lazy<TypeVariable(VM)> defined in androidx.fragment.app

如何使用这个模式?

这一行

private val viewModel: MainViewModel by activityViewModels<MainViewModel>()

应该进入你的 Fragment class,而不是你的其他 ViewModel class。 activityViewModels()是Fragment的函数,不是ViewModel。 ViewModel 不应相互引用。它们的范围限定在 Activity 或 Fragment 的生命周期内,并且没有自己的大写 L 生命周期可供另一个 ViewModel 附加。