我想使用androidx库在Activity中初始化ViewModel
我已经尝试了文档中所说的内容,但是没有用。 “ .of”无法解析。
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import com.example.myapplication.databinding.ActivityMainBinding
MainActivity类:AppCompatActivity(){
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
binding.setLifecycleOwner(this)
var model = ViewModelProvider.of(this).get(SheduleViewModel::class.java)
}
}
of尚未解决,可能还有其他方法可以在androidx中实现
答案 0 :(得分:9)
ViewModels (VM)理论上可以使用Kotlin扩展库import androidx.fragment.app.viewModels
方法by viewmodels()
初始化为类级实例变量。通过将VM初始化为类级别的实例var,可以在类中对其进行访问。
问题:将VM初始化为类级实例变量而不是在onCreate
内有不利之处吗?
在onCreate
内部使用扩展功能创建VM时,VM仅在onCreate
范围内,并且需要额外的代码来重新分配类级实例变量。
请参阅文档
class Fragment : Fragment() {
private val viewModel: SomeViewModel by viewModels()
private fun observeViewState() {
viewModel.feedViewState.observe(viewLifecycleOwner) { viewState ->
//viewState used here.
}
}
}
class Fragment : Fragment() {
private lateinit var viewModel: SomeViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val viewModel: ContentViewModel by viewModels()
this.viewModel = viewModel
}
private fun observeViewState() {
viewModel.feedViewState.observe(viewLifecycleOwner) { viewState ->
//viewState used here.
}
}
}
// Override ViewModelProvider.NewInstanceFactory to create the ViewModel (VM).
class SomeViewModelFactory(private val someString: String): ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T = SomeViewModel(someString) as T
}
class SomeViewModel(private val someString: String) : ViewModel() {
init {
//TODO: Use 'someString' to init process when VM is created. i.e. Get data request.
}
}
class Fragment: Fragment() {
// Create VM in activity/fragment with VM factory.
val someViewModel: SomeViewModel by viewModels { SomeViewModelFactory("someString") }
}
class SomeViewModelFactory(
private val owner: SavedStateRegistryOwner,
private val someString: String) : AbstractSavedStateViewModelFactory(owner, null) {
override fun <T : ViewModel?> create(key: String, modelClass: Class<T>, state: SavedStateHandle) =
SomeViewModel(state, someString) as T
}
class SomeViewModel(private val state: SavedStateHandle, private val someString: String) : ViewModel() {
val feedPosition = state.get<Int>(FEED_POSITION_KEY).let { position ->
if (position == null) 0 else position
}
init {
//TODO: Use 'someString' to init process when VM is created. i.e. Get data request.
}
fun saveFeedPosition(position: Int) {
state.set(FEED_POSITION_KEY, position)
}
}
class Fragment: Fragment() {
// Create VM in activity/fragment with VM factory.
val someViewModel: SomeViewModel by viewModels { SomeViewModelFactory(this, "someString") }
private var feedPosition: Int = 0
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
someViewModel.saveFeedPosition((contentRecyclerView.layoutManager as LinearLayoutManager)
.findFirstVisibleItemPosition())
}
override fun onViewStateRestored(savedInstanceState: Bundle?) {
super.onViewStateRestored(savedInstanceState)
feedPosition = someViewModel.feedPosition
}
}
答案 1 :(得分:3)
PS。这是给使用Java并像我一样卡住了一段时间的人提供的,这样的答案一直在Google中出现。
显然,截至该日期(2020年5月6日),API发生了变化,我必须这样做才能使其正常工作。
// 1. Create a ViewModel Class Let's call it AppStateViewModel
// 2. Put below code Inside Activity onCreate like this:
ViewModelProvider.Factory factory = new ViewModelProvider.NewInstanceFactory();
appStateManager = new ViewModelProvider(this, factory).get(AppStateViewModel.class);
答案 2 :(得分:2)
添加androidx.lifecycle:lifecycle-extensions:$lifecycleExtensionsVersion
依赖项以导入ViewModelProviders
。
答案 3 :(得分:1)
(操作方法)使用 Android体系结构组件中的ViewModel
:
添加Google Maven存储库(可选,只需验证一下即可)
默认未将Android Studio项目配置为访问此存储库。
要将其添加到您的项目中,请打开项目的build.gradle
文件(而不是您的应用程序或模块的文件),然后添加 google()
< / strong>存储库,如下所示:
allprojects {
repositories {
google()
jcenter()
}
}
声明依赖项
打开您的应用级build.gradle
文件,
转到 dependencies{}
块
为{strong> AndroidX 版本,{strong> $ lifecycle_version 版本输入implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
是这里定义的最新版本。
对于Android X之前的版本,请使用implementation "android.arch.lifecycle:viewmodel:1.1.1"
(我猜这是该工件的最新版本1.1.1。)
在您的活动中,使用这种语法
导入此类:
import androidx.lifecycle.ViewModelProviders;
for AndroidX
import android.arch.lifecycle.ViewModelProviders;
在使用 Android X之前的版本
并按照以下步骤获取ViewModel
ViewModelProviders.of(this).get(ProfileObservableViewModel::class.java)
// Kotlin语法
----或----
ViewModelProviders.of(this).get(ProfileObservableViewModel.class);
// Java语法
答案 4 :(得分:1)
ViewModelProviders:不推荐使用此类。直接将构造函数用于ViewModelProvider。
科特林
中的示例这是直接使用ViewModelProvider的方式:
如果您的视图模型仅使用一个参数(应用程序)扩展了 AndroidViewModel ,则您可以使用默认的AndroidViewModelFactory,而不必编写新工厂。示例:
// Activity / fragment class
private lateinit var viewModel: MyOwnAndroidViewModel
// onCreate
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory(application)
).get(MyOwnAndroidViewModel::class.java)
如果您的视图模型仅扩展了 ViewModel 而没有额外的参数,请使用NewInstanceFactory()。
// Activity / fragment class
private lateinit var viewModel: MyOwnViewModel
// onCreate
viewModel = ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
).get(MyOwnViewModel::class.java)
上述亚当的答案也涵盖了其他变化形式。
免责声明:仍在学习基础的Android开发-如果代码有任何问题,请在评论中告诉我。
答案 5 :(得分:1)
对我来说,唯一有效的方法:
implementation 'androidx.fragment:fragment:1.2.4'