我在ViewModel中使用Transformations.switchMap
,因此在片段中观察到的LiveData
集合会对code
参数的更改做出React。
这非常有效:
public class MyViewModel extends AndroidViewModel {
private final LiveData<DayPrices> dayPrices;
private final MutableLiveData<String> code = new MutableLiveData<>();
// private final MutableLiveData<Integer> nbDays = new MutableLiveData<>();
private final DBManager dbManager;
public MyViewModel(Application application) {
super(application);
dbManager = new DBManager(application.getApplicationContext());
dayPrices = Transformations.switchMap(
code,
value -> dbManager.getDayPriceData(value/*, nbDays*/)
);
}
public LiveData<DayPrices> getDayPrices() {
return dayPrices;
}
public void setCode(String code) {
this.code.setValue(code);
}
/*public void setNbDays(int nbDays) {
this.nbDays.setValue(nbDays);
}*/
}
public class MyFragment extends Fragment {
private MyViewModel myViewModel;
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
myViewModel.setCode("SO");
//myViewModel.setNbDays(30);
myViewModel.getDayPrices().observe(MyFragment.this, dataList -> {
// update UI with data from dataList
});
}
问题
现在我需要另一个参数(上面代码中注解的nbDays
),以便LiveData
对象对两个参数的更改(code
和nbDays
)都做出React。
如何链接转换?
一些阅读指向我MediatorLiveData,但它并没有解决我的问题(仍然需要调用带有2个参数的单个DB函数,我不需要合并2个liveDatas)。
所以我尝试用这个代替switchMap
,但是code
和nbDays
总是空的。
dayPrices.addSource(
dbManager.getDayPriceData(code.getValue(), nbDays.getValue),
apiResponse -> dayPrices.setValue(apiResponse)
);
一个解决方案是将一个对象作为单个参数传递,我非常肯定有一个简单的解决方案。
5条答案
按热度按时间db2dz4w81#
来源:https://plus.google.com/+MichielPijnackerHordijk/posts/QGXF9gRomVi
要使
switchMap()
具有多个触发器,您需要使用自定义MediatorLiveData
来观察LiveData对象的组合-你就能做到-
如果使用Kotlin并希望使用泛型:
然后:
bgibtngc2#
@jL4提出的自定义
MediatorLiveData
工作得很好,可能是解决方案。我只想分享我认为最简单的解决方案,即使用一个内部类来表示组合过滤器值:
然后在活动/片段中:
mwngjboj3#
jL 4答案的简化,(在Kotlin中也是如此,以防对任何人有帮助)......无需为此创建自定义类:
说明
firstLiveData
或secondLiveData
中的任何更新都将更新combinedValues
的值,并将这两个值作为一对发出(这要感谢jL 4)。调用
liveData.value
可以为空,因此此解决方案使Pair中的值可为空,以避免空指针异常。因此,对于实际的results/datasource调用,开关Map位于
combinedValues
活动数据上,从Pair
中提取2个值并执行空值检查,因此可以确保将非空值传递到数据源。bejyjqdl4#
我也遇到过类似的问题。有两种方法可以解决这个问题:
1.要么使用
MediatorLiveData
1.使用RxJava,因为它有各种各样的操作符来完成这种复杂的事情
如果你不知道RxJava,那么我建议你编写自定义的
MediatorLiveData
类。要学习如何编写自定义的MediatorLiveData
类,请查看以下示例:https://gist.github.com/AkshayChordiya/a79bfcc422fd27d52b15cdafc55eac6bbbmckpt75#
我使用以下类来转换许多不同类型的实时数据
用法:请注意,工作逻辑略有不同。导致更新的LiveData(signalledLiveData)作为参数传递给转换侦听器,而不是所有LiveData的值。您可以通过value属性以常规方式自己获取当前LiveData值。
示例: