问题标签 [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.

0 投票
13 回答
55141 浏览

android - LiveData 防止在开始观察时收到最后一个值

LiveData开始观察时是否可以阻止接收最后一个值?我正在考虑LiveData用作事件。

例如显示消息、导航事件或对话触发器等事件,类似于EventBus.

ViewModel与fragment之间的通信有关的问题,谷歌让我们LiveData用数据更新视图,但是这种类型的通信不适合我们只需要用单个事件更新视图一次,而且我们不能保存视图的引用ViewModel并调用一些方法,因为它会造成内存泄漏。

我发现了类似的SingleLiveEvent - 但它仅适用于 1 个观察者,而不适用于多个观察者。

- - 更新 - -

正如@EpicPandaForce所说“没有理由将LiveData用作它不是的东西”,问题的意图可能是MVVM中视图和ViewModel之间的通信与LiveData

0 投票
2 回答
1579 浏览

android - 如何生成具有临时子视图的组合视图模型?

设想

我有一个测验生成器,它生成一系列不同类别的测验。该序列的长度不受限制。

测验生成器有一个视图模型。每种类型的测验都有一个视图模型。测验生成器视图模型应该根据它们的类创建测验的视图模型。

问题

视图模型不能包含对生命周期的引用,但我需要生命周期来创建视图模型。

问题

我在哪里创建测验的子视图模型?

我能想到的一种解决方案是每次都从活动中注入子视图模型。这是一个弯路,尤其是在涉及嵌套视图的情况下。

另一种解决方案是在嵌套视图中创建视图模型,这看起来也很丑陋,因为从视图内部访问生命周期并不常见。

如果没有干净的解决方案,我的架构方法有什么问题?我应该在这种情况下使用片段吗?

0 投票
2 回答
3185 浏览

android - 架构组件刷新 LiveData

我正在努力使用架构组件在主从视图上刷新数据的正确方法。我有一个单头主活动,显示最喜欢的电影列表。当我转到详细信息视图时,从收藏夹中添加/删除电影并关闭主视图的详细信息视图,数据保持不同步。我在 onCreate 方法中初始化视图模型:

View Model 也很简单:

最简单的解决方案是每次激活视图时强制刷新视图:

但我不太喜欢这种方法,因为当屏幕方向发生变化以及活动来自后台时,它会导致刷新。

也可以仅在结果发生更改时启动结果的详细信息活动并刷新数据,但我也不认为在反应式方法中应该这样做。

此外,我正在考虑订阅 cotent 解析器中的数据库更改,并在每次数据更改时使用新内容更新 Flowable,但我确信它是否会起作用,因为当更改发生时,实时数据观察者(主视图)在暂停模式,所以它不会被通知,对吗?

0 投票
1 回答
709 浏览

android - 通过 parcelable 传递对象或从 DB 加载

我正在练习 MVVM 模型以及 Room 和 LiveData 库。困扰我的一个实现问题是,当我开始一项新活动(例如,产品列表页面到产品详细信息页面)时,我是否应该通过实现 Parcelable 来传递我的产品对象,或者我可以使用 ViewModel 从数据库中加载它。我不确定哪个更好,或者有人可以比较这两种策略的优缺点吗?谢谢!

0 投票
1 回答
1477 浏览

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.

0 投票
4 回答
16329 浏览

android - Android ViewModel 在屏幕旋转时重新创建

我发现ViewModel没有保留架构组件的情况 - 简而言之,如下所示:

  1. Activity 启动并ViewModel创建实例
  2. 活动被置于后台
  3. 设备屏幕旋转
  4. 活动被放回前台
  5. 调用ViewModel 的onCleared方法并创建新对象

ViewModel在这种情况下,我的实例被破坏是Android 的正常行为吗?如果是这样,是否有任何建议的解决方案来保持其状态?

我能想到的一种方法onCleared是调用一次保存它,但是,只要活动实际完成,它也会保持状态。另一种方法可能是使用,onRestoreInstanceState但它会在每次屏幕旋转时触发(不仅在应用程序处于后台时)。

有什么灵丹妙药可以处理这种情况吗?

0 投票
1 回答
1514 浏览

android - 如果我清理后面的引用,我可以观察 ViewModel 吗?

建议的实现方式是通过使用对象到活动、片段和视图ViewModel来公开变化的数据。LiveData在某些情况下,当LiveData不是一个理想的答案或根本没有答案时。

自然的替代方法是将观察者模式应用于ViewModel,使其成为可观察的。当向 注册观察者时ViewModelViewModel将持有回调引用以通知观察者。

文档说,aViewModel不得包含对活动、片段或视图的引用。我发现“为什么”这个问题的唯一答案是,这可能会导致内存泄漏。那么如何清理引用以避免内存泄漏呢?

对于视图,这是一个困难。当视野消失时,没有明确的时刻。但是活动和片段具有定义的生命周期。所以有些地方可以取消注册为观察员。

你怎么看?ViewModels如果您注意始终取消注册活动,那么将活动注册为观察者是否有效?您是否找到有关此问题的任何有效信息?

我为最佳答案设置了一个小奖励。这不是因为我认为它是推荐的解决方案(因为它不适用于视图)。我只想知道并扩展我的选择。

0 投票
1 回答
1604 浏览

firebase - FirebaseAuth.AuthStateListener 使用 LiveData。下面的实现有改进的余地吗?

在实施架构组件方面是否有改进的余地或一般考虑:

  1. 注意:如果您选择使用 AuthStateListener,请确保在启动 FirebaseUI 流程之前取消注册,并在流程返回后重新注册。FirebaseUI 在内部执行身份验证操作,这可能会在流程完成之前触发侦听器。

实时数据

视图模型

主要活动

0 投票
0 回答
934 浏览

android - 其项目的 RecycleView 和 ViewModels

Google 引入了新的架构组件,包括 ViewModels、LiveData 等。

我尝试在不使用 DataBinding的情况下将 RecycleView 项目和新 ViewModel 放在一起。

实际上,我确实有非常简单的事情,并且在我的脑海中有一种算法,但不知道如何实现它。

每个 RecyclerView 项目都包含一个可展开的列表。因此,如果用户单击显示更多/显示更少按钮,则应切换内部列表的可见性。

我的想法:

  • 我需要在每个项目的 ViewHolder 中注入一个 ViewModel。

  • 我会订阅关于内部列表可见性的 LiveData-Changes。

  • 在显示更多/更少点击时,我会调用 viewModel.showMoreClicked 并更改可见性。

也许您有一个链接或正确的解决方案(以及没有数据绑定的解决方案)。

我也可以想象,我的做法是错误的。

0 投票
1 回答
1191 浏览

android - 数据未更改时调用 Android ViewModel onChanged

我有一个Fragment, 具有动态数量的自定义视图,由一个EditText和一个组成Button。我所做的是,每次用户在 中键入价格EditText并单击 时Button,我都会通过 ViewModel 发出 API 请求,Fragment然后LiveDataViewModel.

到目前为止一切顺利,当我使用第一个自定义视图时。问题出现在第二个(和第三个)上,因为onChanged()即使数据没有更改,该方法显然也被调用了,并且第二个和第三个自定义视图正在侦听该数据,所以当它们不是时它们会改变触发数据更改(他们从第一个接收数据更改)。

当用户点击 时Button,我观察和获取价格的方式是这样的:

发生的事情是processResponse当第二个自定义视图触发 API 请求时调用该方法,但我收到的结果是coinDayAveragePriceAPI 响应到达之前的结果(这是来自第一个自定义视图的第一个 API 响应之后的值已经到达)。

这是我的一部分ViewModel

NetworkViewState只是sealed class作为 API 请求响应的包装器:

}

我也尝试取消订阅或将其设置coinDayAveragePrice为 null,但我仍然遇到同样的问题。

提前非常感谢!