Nur*_*lov 5 android viewmodel android-jetpack
我想使用androidx库在Activity中初始化ViewModel
我已经尝试了文档中说的内容,但是没有用。“ .of”未解析。
import androidx.appcompat.app.AppCompatActivity
Run Code Online (Sandbox Code Playgroud)
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)
}
Run Code Online (Sandbox Code Playgroud)
}
的尚未解决,可能是在androidx中有其他方法
Ada*_*itz 14
所述的ViewModels(VM)的可理论上被初始化为使用科特林扩展库类水平的实例变量import androidx.fragment.app.viewModels的方法by viewmodels()。通过将 VM 初始化为类级别实例 var,可以在类中访问它。
问题:将 VM 初始化为类级别实例变量而不是 inside 是否有缺点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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
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.
}
}
}
Run Code Online (Sandbox Code Playgroud)
// 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") }
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
附注。这是针对那些使用 Java 并像我一样卡住了一段时间的人来说的,这个 SO 答案一直出现在谷歌中。
显然,截至该日期(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);
Run Code Online (Sandbox Code Playgroud)
小智 6
对我来说,唯一有效的方法是:
implementation 'androidx.fragment:fragment:1.2.4'
Run Code Online (Sandbox Code Playgroud)
在您的应用程序 gradle 文件中,确保您已添加以下依赖项:
对于活动用途:
implementation "androidx.activity:activity-ktx:1.4.1"
Run Code Online (Sandbox Code Playgroud)
对于片段使用:
implementation 'androidx.fragment:fragment:1.4.1'
Run Code Online (Sandbox Code Playgroud)
更新的答案:
事情改变了一点点,因为以前需要依赖- ViewModelProviders- 得到了弃用(详见旧的答案)。您现在可以ViewModelProvider直接使用构造函数。
因此,在这种情况下,答案将是:
private val viewModel = ViewModelProvider(this).get(SheduleViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
需要注意的是,但是,如果你实例化一个ViewModel在Fragment,你可以添加androidx.fragment:fragment-ktx:$Version依赖关系,然后利用财产代表团:
private val viewModel: SheduleViewModel by viewModels()
Run Code Online (Sandbox Code Playgroud)
它在内部将使用ViewModelProvider和范围的ViewModel给你Fragment。这只是编写相同内容的一种更简洁的方式。
无论是ViewModelProvider构造和by viewModels()也接受工厂作为参数(注入您有用ViewModel):
private val viewModel =
ViewModelProvider(this, viewModelFactory).get(SheduleViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
和
private val viewModel: SheduleViewModel by viewModels { viewModelFactory }
Run Code Online (Sandbox Code Playgroud)
使用最适合您的一种。
旧答案:
添加androidx.lifecycle:lifecycle-extensions:$lifecycleExtensionsVersion依赖项以便导入ViewModelProviders。
ViewModelProviders:此类已弃用。直接使用 ViewModelProvider 的构造函数。
Kotlin中的示例
这是直接使用ViewModelProvider 的方法:
如果您的视图模型仅使用一个参数(即应用程序)扩展AndroidViewModel ,那么您可以使用默认的AndroidViewModelFactory,而无需编写新的 Factory。例子:
// Activity / fragment class
private lateinit var viewModel: MyOwnAndroidViewModel
// onCreate
viewModel = ViewModelProvider(
this,
ViewModelProvider.AndroidViewModelFactory(application)
).get(MyOwnAndroidViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
如果您的视图模型仅扩展ViewModel而没有额外的参数,则使用NewInstanceFactory()。
// Activity / fragment class
private lateinit var viewModel: MyOwnViewModel
// onCreate
viewModel = ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
).get(MyOwnViewModel::class.java)
Run Code Online (Sandbox Code Playgroud)
亚当的上述回答也涵盖了其他变化。
免责声明:仍在学习基本的 Android 开发 - 如果代码有任何问题,请在评论中告诉我。
| 归档时间: |
|
| 查看次数: |
2314 次 |
| 最近记录: |