android - Android ViewModel 参考 Fragment
问题描述
我是一名初学者 android 开发人员,正在寻找编写一个完整的喷气背包应用程序。我想知道与 ViewModel 中的片段进行通信的最佳方式是说、显示对话框或导航到另一个片段。
我有这样的事情:
class Foo: ViewModel() {
interface Callbacks {
fun doSomethingWithUI()
fun showBaz()
}
var callbacks: Callbacks? = null
}
然后在片段 onCreate 中,它将自己设置为 viewmodels 回调对象。
查看文档,它指出 ViewModel 不应该保留任何相关的视图或生命周期,或者对活动的引用。考虑到这一点,ViewModel 正在引用具有活动的片段。
我想知道,为什么会这么糟糕。一切似乎都正常工作,如果只有一个活动开始,我们会泄漏什么?为什么谷歌很清楚不要抓住这些东西,但从来没有真正说为什么不这样做。
另外,由于我正在做的事情不好,让 ViewModel 告诉片段说“显示带有此错误的对话框”的“正确”方式是什么
解决方案
您可以首先将实时数据创建为 Mutable 和 Immutable 两部分。可变的实时数据将仅在 viewModel 内部使用,而不可变的数据可以从片段或活动中观察到。
class CarViewModel: ViewModel() {
private val repo: EngineRepo() // an instance of your repository inside ViewModel
private val _engine = MutableLiveData<List<Engines>>() //mutable live data to be used inside the viewModel
val : LiveData<List<Engines>> = _engine //this is the observable live data
现在,
fun fetchEngineDetails() {
viewModelScope.launch(Dispatchers.IO){
_engine.postValue(repo.getEngine()) // calling the function inside your repo
}
}
现在你已经完成了你的 viewModel 所以,在你的片段中调用这个 ViewModel 假设你可以创建一个 ViewModel 类的实例。
class CarFragment: Fragment(){
private val carViewModel: CarViewModel by viewModels()
现在在您的 onCreate 方法中,您可以使用 ViewModel 调用该函数,如下所示:
varViewModel.fetchEngineDetails()
在 onCreateView 中,您可以像这样观察 livedata:
carViewModel.engine.observe {(viewlifeCycleOwner)} {
Toast.makeText(requireContext, "Number of engines is {it.size}, Toast.LENGTH_SHORT).show()
}
请注意,要按照我在此处编写的方式在片段中使用或创建 ViewModel 类的实例,您必须在您的 gradles 中放置一些依赖项
所以在你 build.gradle (Project)
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.3.5"
在你的 build.gradle(App Module)
内部插件添加:
id 'androidx.navigation.safeargs.kotlin'
和内部依赖项添加:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
implementation "android.arch.lifecycle:extensions:1.1.1"
推荐阅读
- alert - 当警报管理器触发脚本应该执行时,我想通过 prometheus 警报管理器执行 shell 脚本
- android - Flutter Isolate,将 RepaintBoundary 的 GlobalKey 发送到 Isolate
- linux - 如何保留命令输出中的换行符并使用 ansible 复制模块将其写入文件
- node.js - 为什么在子集合中创建多个文档后,我收到 Cloud Function 内存泄漏警告?
- firebase - google-services.json 文件有时间限制(有效期)吗?
- kotlin - MVVM kotlin 中的 LiveData Observer 首先返回之前的结果
- java - 响应 403 无效的 CSRF 令牌
- python - 以x轴0.05的固定间隔提取Y轴的值
- android - 如何在 android 中获取 HLS(.m3u8) 视频链接的持续时间?
- reactjs - 打包一个自定义的 Material UI ThemeProvider 组件