问题标签 [android-viewmodel]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
android - LiveData 防止在开始观察时收到最后一个值
LiveData
开始观察时是否可以阻止接收最后一个值?我正在考虑LiveData
用作事件。
例如显示消息、导航事件或对话触发器等事件,类似于EventBus
.
ViewModel
与fragment之间的通信有关的问题,谷歌让我们LiveData
用数据更新视图,但是这种类型的通信不适合我们只需要用单个事件更新视图一次,而且我们不能保存视图的引用ViewModel
并调用一些方法,因为它会造成内存泄漏。
我发现了类似的SingleLiveEvent - 但它仅适用于 1 个观察者,而不适用于多个观察者。
- - 更新 - -
正如@EpicPandaForce所说“没有理由将LiveData用作它不是的东西”,问题的意图可能是MVVM中视图和ViewModel之间的通信与LiveData
android - 如何生成具有临时子视图的组合视图模型?
设想
我有一个测验生成器,它生成一系列不同类别的测验。该序列的长度不受限制。
测验生成器有一个视图模型。每种类型的测验都有一个视图模型。测验生成器视图模型应该根据它们的类创建测验的视图模型。
问题
视图模型不能包含对生命周期的引用,但我需要生命周期来创建视图模型。
问题
我在哪里创建测验的子视图模型?
我能想到的一种解决方案是每次都从活动中注入子视图模型。这是一个弯路,尤其是在涉及嵌套视图的情况下。
另一种解决方案是在嵌套视图中创建视图模型,这看起来也很丑陋,因为从视图内部访问生命周期并不常见。
如果没有干净的解决方案,我的架构方法有什么问题?我应该在这种情况下使用片段吗?
android - 架构组件刷新 LiveData
我正在努力使用架构组件在主从视图上刷新数据的正确方法。我有一个单头主活动,显示最喜欢的电影列表。当我转到详细信息视图时,从收藏夹中添加/删除电影并关闭主视图的详细信息视图,数据保持不同步。我在 onCreate 方法中初始化视图模型:
View Model 也很简单:
最简单的解决方案是每次激活视图时强制刷新视图:
但我不太喜欢这种方法,因为当屏幕方向发生变化以及活动来自后台时,它会导致刷新。
也可以仅在结果发生更改时启动结果的详细信息活动并刷新数据,但我也不认为在反应式方法中应该这样做。
此外,我正在考虑订阅 cotent 解析器中的数据库更改,并在每次数据更改时使用新内容更新 Flowable,但我确信它是否会起作用,因为当更改发生时,实时数据观察者(主视图)在暂停模式,所以它不会被通知,对吗?
android - 通过 parcelable 传递对象或从 DB 加载
我正在练习 MVVM 模型以及 Room 和 LiveData 库。困扰我的一个实现问题是,当我开始一项新活动(例如,产品列表页面到产品详细信息页面)时,我是否应该通过实现 Parcelable 来传递我的产品对象,或者我可以使用 ViewModel 从数据库中加载它。我不确定哪个更好,或者有人可以比较这两种策略的优缺点吗?谢谢!
android - Dagger2 injection of a ViewModel without @Inject constructor
I have large Android ViewModel classes that tend to have a lot of dependencies (most of them are DAOs from Room, one per SQLite table). Some have more than 10 dependencies.
This is fine but the @Inject
constructor is bloated with arguments, and contains only boilerplate code to set the injected members from the constructor arguments.
I wanted to switch to "regular" injected members, identified individually with an @Inject
annotation, like other (dumb) classes.
This fails for Android related classes (although ViewModels are advertised as non-Android dependent, e.g. they don't use the Android framework) such as activities and fragments.
The workaround for that is to use a factory, which is injected from the Application
class using the nice HasActivityInjector
, HasServiceInjector
, etc. interfaces.
Dagger doesn't provide any HasViewModelInjector
, so if I persist in injecting members individually instead of injecting the constructor, here's what I'm given:
error: [dagger.android.AndroidInjector.inject(T)] XXXViewModel cannot be provided without an @Inject constructor or from an @Provides-annotated method. This type supports members injection but cannot be implicitly provided.
If I create a module that has a @Provides
annotation to create the ViewModel, this doesn't inject individual members.
Did I miss something (my last sentence is what's most important in my question) or is it simply not possible to inject members, and I have to inject the constructor?
A bit of code.
What I want:
versus what I need to do:
First block of code (what I want) requires this method in a module:
but in this case the myDao
field is null. How to inject the @Inject
-annotated members?
I want to avoid the use of the 2nd block of code, which tends to create a huge constructor bloated with many arguments, should I need to inject a lot of members.
android - Android ViewModel 在屏幕旋转时重新创建
我发现ViewModel
没有保留架构组件的情况 - 简而言之,如下所示:
- Activity 启动并
ViewModel
创建实例 - 活动被置于后台
- 设备屏幕旋转
- 活动被放回前台
- 调用ViewModel 的
onCleared
方法并创建新对象
ViewModel
在这种情况下,我的实例被破坏是Android 的正常行为吗?如果是这样,是否有任何建议的解决方案来保持其状态?
我能想到的一种方法onCleared
是调用一次保存它,但是,只要活动实际完成,它也会保持状态。另一种方法可能是使用,onRestoreInstanceState
但它会在每次屏幕旋转时触发(不仅在应用程序处于后台时)。
有什么灵丹妙药可以处理这种情况吗?
android - 如果我清理后面的引用,我可以观察 ViewModel 吗?
建议的实现方式是通过使用对象到活动、片段和视图ViewModel
来公开变化的数据。LiveData
在某些情况下,当LiveData
不是一个理想的答案或根本没有答案时。
自然的替代方法是将观察者模式应用于ViewModel
,使其成为可观察的。当向 注册观察者时ViewModel
,ViewModel
将持有回调引用以通知观察者。
文档说,aViewModel
不得包含对活动、片段或视图的引用。我发现“为什么”这个问题的唯一答案是,这可能会导致内存泄漏。那么如何清理引用以避免内存泄漏呢?
对于视图,这是一个困难。当视野消失时,没有明确的时刻。但是活动和片段具有定义的生命周期。所以有些地方可以取消注册为观察员。
你怎么看?ViewModels
如果您注意始终取消注册活动,那么将活动注册为观察者是否有效?您是否找到有关此问题的任何有效信息?
我为最佳答案设置了一个小奖励。这不是因为我认为它是推荐的解决方案(因为它不适用于视图)。我只想知道并扩展我的选择。
firebase - FirebaseAuth.AuthStateListener 使用 LiveData。下面的实现有改进的余地吗?
在实施架构组件方面是否有改进的余地或一般考虑:
- 注意:如果您选择使用 AuthStateListener,请确保在启动 FirebaseUI 流程之前取消注册,并在流程返回后重新注册。FirebaseUI 在内部执行身份验证操作,这可能会在流程完成之前触发侦听器。
实时数据
视图模型
主要活动
android - 其项目的 RecycleView 和 ViewModels
Google 引入了新的架构组件,包括 ViewModels、LiveData 等。
我尝试在不使用 DataBinding的情况下将 RecycleView 项目和新 ViewModel 放在一起。
实际上,我确实有非常简单的事情,并且在我的脑海中有一种算法,但不知道如何实现它。
每个 RecyclerView 项目都包含一个可展开的列表。因此,如果用户单击显示更多/显示更少按钮,则应切换内部列表的可见性。
我的想法:
我需要在每个项目的 ViewHolder 中注入一个 ViewModel。
我会订阅关于内部列表可见性的 LiveData-Changes。
在显示更多/更少点击时,我会调用 viewModel.showMoreClicked 并更改可见性。
也许您有一个链接或正确的解决方案(以及没有数据绑定的解决方案)。
我也可以想象,我的做法是错误的。
android - 数据未更改时调用 Android ViewModel onChanged
我有一个Fragment
, 具有动态数量的自定义视图,由一个EditText
和一个组成Button
。我所做的是,每次用户在 中键入价格EditText
并单击 时Button
,我都会通过 ViewModel 发出 API 请求,Fragment
然后LiveData
在ViewModel
.
到目前为止一切顺利,当我使用第一个自定义视图时。问题出现在第二个(和第三个)上,因为onChanged()
即使数据没有更改,该方法显然也被调用了,并且第二个和第三个自定义视图正在侦听该数据,所以当它们不是时它们会改变触发数据更改(他们从第一个接收数据更改)。
当用户点击 时Button
,我观察和获取价格的方式是这样的:
发生的事情是processResponse
当第二个自定义视图触发 API 请求时调用该方法,但我收到的结果是coinDayAveragePrice
API 响应到达之前的结果(这是来自第一个自定义视图的第一个 API 响应之后的值已经到达)。
这是我的一部分ViewModel
:
NetworkViewState
只是sealed class
作为 API 请求响应的包装器:
}
我也尝试取消订阅或将其设置coinDayAveragePrice
为 null,但我仍然遇到同样的问题。
提前非常感谢!