是否可以使两个LiveData中的一个LiveData? [英] Is it possible to make one LiveData of two LiveDatas?
问题描述
我有两个DAO,两个存储库和两个POJO.有什么方法可以创建两个Livedata?我需要它来制作Recyclerview的单个列表. POJO是相似的对象.
ExpenseRepository:
public class ExpenseRepository {
private ExpenseDao expenseDao;
private LiveData<List<Expense>> allExpenses;
public ExpenseRepository(Application application) {
ExpenseIncomeDatabase database = ExpenseIncomeDatabase.getInstance(application);
expenseDao = database.expenseDao();
allExpenses = expenseDao.getExpensesByDay();
}
public LiveData<List<Expense>> getAllExpensesByDay() {
return allExpenses;
}
IncomeRepository:
public class IncomeRepository {
private IncomeDao incomeDao;
private LiveData<List<Income>> allIncomes;
public IncomeRepository(Application application) {
ExpenseIncomeDatabase database = ExpenseIncomeDatabase.getInstance(application);
incomeDao = database.incomeDao();
allIncomes = incomeDao.getIncomesByDay();
}
public LiveData<List<Income>> getAllIncomesByDay() {
return allIncomes;
}
ExpenseDao:
@Dao
public interface ExpenseDao {
@Query("SELECT * FROM expense_table ORDER BY day")
LiveData<List<Expense>> getExpensesByDay();
IncomeDao:
@Dao
public interface IncomeDao {
@Query("SELECT * FROM income_table ORDER BY day")
LiveData<List<Income>> getIncomesByDay();
DailyViewModel:
public class DailyFragmentViewModel extends AndroidViewModel {
private ExpenseRepository expenseRepository;
private IncomeRepository incomeRepository;
private LiveData<Pair<List<Expense>, List<Income>>> combined;
private ExpenseDao expenseDao;
private IncomeDao incomeDao;
public DailyFragmentViewModel(@NonNull Application application) {
super(application);
expenseRepository = new ExpenseRepository(application);
incomeRepository = new IncomeRepository(application);
combined = new DailyCombinedLiveData(expenseDao.getExpensesByDay(), incomeDao.getIncomesByDay());
}
public LiveData<Pair<List<Expense>, List<Income>>> getExpensesAndIncomes() {
return combined;
}
我假设您想将它们合并,是吗?您将需要一个MediatorLiveData,但是那个说您现在需要Object的人是错误的.您需要的是MediatorLiveData<Pair<List<Expense>, List<Income>>>
.
public class CombinedLiveData extends MediatorLiveData<Pair<List<Expense>, List<Income>>> {
private List<Expense> expenses = Collections.emptyList();
private List<Income> incomes = Collections.emptyList();
public CombinedLiveData(LiveData<List<Expense>> ld1, LiveData<List<Income>> ld2) {
setValue(Pai.create(expenses, incomes));
addSource(ld1, (expenses) -> {
if(expenses != null) {
this.expenses = expenses;
}
setValue(Pair.create(expenses, incomes));
});
addSource(ld2, (incomes) -> {
if(incomes != null) {
this.incomes = incomes;
}
setValue(Pair.create(expenses, incomes));
});
}
}
您可能会将此类型设为通用,这将是使用两个两元组(Pair)的元组对两个LiveData的combineLatest
的实现.
:
public class CombinedLiveData2<A, B> extends MediatorLiveData<Pair<A, B>> {
private A a;
private B b;
public CombinedLiveData2(LiveData<A> ld1, LiveData<B> ld2) {
setValue(Pair.create(a, b));
addSource(ld1, (a) -> {
if(a != null) {
this.a = a;
}
setValue(Pair.create(a, b));
});
addSource(ld2, (b) -> {
if(b != null) {
this.b = b;
}
setValue(Pair.create(a, b));
});
}
}
请注意,在这种情况下,我失去了将Collections.emptyList()
设置为A
和B
的初始值的能力,并且在访问该对中的数据时,您将需要检查null
./p>
:您可以使用库 https://github .com/Zhuinden/livedata-combinetuple-kt 会执行相同的操作.
I have two DAOs, two Repositories and two POJOs. There is some way to create one Livedata of two? I need it to make single list for Recyclerview. POJOs are similar objects.
ExpenseRepository:
public class ExpenseRepository {
private ExpenseDao expenseDao;
private LiveData<List<Expense>> allExpenses;
public ExpenseRepository(Application application) {
ExpenseIncomeDatabase database = ExpenseIncomeDatabase.getInstance(application);
expenseDao = database.expenseDao();
allExpenses = expenseDao.getExpensesByDay();
}
public LiveData<List<Expense>> getAllExpensesByDay() {
return allExpenses;
}
IncomeRepository:
public class IncomeRepository {
private IncomeDao incomeDao;
private LiveData<List<Income>> allIncomes;
public IncomeRepository(Application application) {
ExpenseIncomeDatabase database = ExpenseIncomeDatabase.getInstance(application);
incomeDao = database.incomeDao();
allIncomes = incomeDao.getIncomesByDay();
}
public LiveData<List<Income>> getAllIncomesByDay() {
return allIncomes;
}
ExpenseDao:
@Dao
public interface ExpenseDao {
@Query("SELECT * FROM expense_table ORDER BY day")
LiveData<List<Expense>> getExpensesByDay();
IncomeDao:
@Dao
public interface IncomeDao {
@Query("SELECT * FROM income_table ORDER BY day")
LiveData<List<Income>> getIncomesByDay();
DailyViewModel:
public class DailyFragmentViewModel extends AndroidViewModel {
private ExpenseRepository expenseRepository;
private IncomeRepository incomeRepository;
private LiveData<Pair<List<Expense>, List<Income>>> combined;
private ExpenseDao expenseDao;
private IncomeDao incomeDao;
public DailyFragmentViewModel(@NonNull Application application) {
super(application);
expenseRepository = new ExpenseRepository(application);
incomeRepository = new IncomeRepository(application);
combined = new DailyCombinedLiveData(expenseDao.getExpensesByDay(), incomeDao.getIncomesByDay());
}
public LiveData<Pair<List<Expense>, List<Income>>> getExpensesAndIncomes() {
return combined;
}
I assume you want to combine them, yes? You'll need a MediatorLiveData, but the guy saying you now need Object is wrong. What you need is a MediatorLiveData<Pair<List<Expense>, List<Income>>>
.
public class CombinedLiveData extends MediatorLiveData<Pair<List<Expense>, List<Income>>> {
private List<Expense> expenses = Collections.emptyList();
private List<Income> incomes = Collections.emptyList();
public CombinedLiveData(LiveData<List<Expense>> ld1, LiveData<List<Income>> ld2) {
setValue(Pai.create(expenses, incomes));
addSource(ld1, (expenses) -> {
if(expenses != null) {
this.expenses = expenses;
}
setValue(Pair.create(expenses, incomes));
});
addSource(ld2, (incomes) -> {
if(incomes != null) {
this.incomes = incomes;
}
setValue(Pair.create(expenses, incomes));
});
}
}
You could potentially make this generic and it'd be the implementation of combineLatest
for two LiveData using tuples of 2-arity (Pair).
EDIT: like this:
public class CombinedLiveData2<A, B> extends MediatorLiveData<Pair<A, B>> {
private A a;
private B b;
public CombinedLiveData2(LiveData<A> ld1, LiveData<B> ld2) {
setValue(Pair.create(a, b));
addSource(ld1, (a) -> {
if(a != null) {
this.a = a;
}
setValue(Pair.create(a, b));
});
addSource(ld2, (b) -> {
if(b != null) {
this.b = b;
}
setValue(Pair.create(a, b));
});
}
}
Beware that I lost the ability to set Collections.emptyList()
as initial values of A
and B
with this scenario, and you WILL need to check for null
s when you access the data inside the pair.
EDIT: You can use the library https://github.com/Zhuinden/livedata-combinetuple-kt which does the same thing.
这篇关于是否可以使两个LiveData中的一个LiveData?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!