Kotlin 中的接收器类型与 Android 的"活动视图模型"不匹配



多年没有接触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
}
}

我小心地给我的build.gradle添加了这些dependencies:

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被突出显示为红色,错误是:

未解决的参考。由于接收方类型不匹配,以下候选者均不适用:public inline fun <reified VM : ViewModel> Fragment.activityViewModels(noinline factoryProducer: (() -> ViewModelProvider.Factory)? = ...): Lazy<TypeVariable(VM)>定义于androidx.fragment.app

如何使用这个模式?

这一行

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

应该放在Fragment类中,而不是其他ViewModel类中。activityViewModels()是Fragment的函数,而不是ViewModel的函数。ViewModels不应该相互引用。它们被限定在Activity或Fragment的生命周期范围内,并且没有自己的大写l生命周期,这样另一个ViewModel就可以附加到它上面。

最新更新