问题描述
我在ViewModel中使用 Transformations.switchMap
在片段中观察到的我的LiveData
集合对code
参数的更改有反应.
I am using Transformations.switchMap
in my ViewModel so my LiveData
collection, observed in my fragment, reacts on changes of code
parameter.
这很完美:
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
)都做出反应.
I now need another parameter (nbDays
commented in the code above), so that my LiveData
object reacts on both parameters change (code
and nbDays
).
如何链接转换?
一些阅读将我指向 MediatorLiveData ,但确实如此不能解决我的问题(仍然需要使用2个参数调用单个DB函数,我不需要合并2个liveDatas).
Some reading pointed me to MediatorLiveData, but it does not solve my problem (still need to call single DB function with 2 parameters, I don't need to merge 2 liveDatas).
因此,我尝试使用此方法而不是switchMap
,但code
和nbDays
始终为空.
So I tried this instead of switchMap
but code
and nbDays
are always null.
dayPrices.addSource(
dbManager.getDayPriceData(code.getValue(), nbDays.getValue),
apiResponse -> dayPrices.setValue(apiResponse)
);
一种解决方案是将对象作为单个参数传递,因为我很确定对此有一个简单的解决方案.
One solution would be to pass an object as single parameter by I'm pretty sure there is a simple solution to this.
推荐答案
来源: https://plus.google.com/+MichielPijnackerHordijk/posts/QGXF9gRomVi
要具有多个switchMap()
触发器,您需要使用自定义MediatorLiveData
来观察LiveData对象的组合-
To have multiple triggers for switchMap()
, you need to use a custom MediatorLiveData
to observe the combination of the LiveData objects -
class CustomLiveData extends MediatorLiveData<Pair<String, Integer>> {
public CustomLiveData(LiveData<String> code, LiveData<Integer> nbDays) {
addSource(code, new Observer<String>() {
public void onChanged(@Nullable String first) {
setValue(Pair.create(first, nbDays.getValue()));
}
});
addSource(nbDays, new Observer<Integer>() {
public void onChanged(@Nullable Integer second) {
setValue(Pair.create(code.getValue(), second));
}
});
}
}
然后您可以执行此操作-
Then you can do this -
CustomLiveData trigger = new CustomLiveData(code, nbDays);
LiveData<DayPrices> dayPrices = Transformations.switchMap(trigger,
value -> dbManager.getDayPriceData(value.first, value.second));
如果您使用Kotlin并想使用泛型:
If you use Kotlin and want to work with generics:
class DoubleTrigger<A, B>(a: LiveData<A>, b: LiveData<B>) : MediatorLiveData<Pair<A?, B?>>() {
init {
addSource(a) { value = it to b.value }
addSource(b) { value = a.value to it }
}
}
然后:
val dayPrices = Transformations.switchMap(DoubleTrigger(code, nbDays)) {
dbManager.getDayPriceData(it.first, it.second)
}
这篇关于具有多个参数的MediatorLiveData或switchMap转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!