My project is an expense tracker where I show a list of Dates under which I have a list of expenses that happened on those dates. I have nested RecyclerViews. Parent RecyclerView is a list of unique dates of all expenses. Child RecyclerView is list of expenses (viewed, of course, under unique dates). My ViewModel has a list of LiveData of ExpenseEntity. The ViewModel has to have a list of LiveData of Date which contains unique dates. I get my list of ExpenseEntity from a Room database.
My main fragments observes the LiveData of ExpenseEntities because then is when I need to update my parent and child recyclerviews.
I cannot figure out how to use Transformations.map to have a live transforming list of unique dates. How should I make sure the LiveData of Dates is always updated once LiveData of ExpenseEntity is updated?
MainActivityViewModel.kt
class MainActivityViewModel(private val expenseDao: ExpenseDao) : ViewModel() {
val allExpenses : LiveData<List<ExpenseEntity>> = expenseDao.fetchAllExpenses().asLiveData()
val uniqueDates : LiveData<List<Date>> = Transformations.map(allExpenses) {
it.map { expense ->
expense.date!!
}.distinct()
}
...
}
ExpensesFragment.kt
val factory = MainActivityViewModelFactory((activity?.application as SimpleExpenseTrackerApp).db.expenseDao())
expensesViewModel = ViewModelProvider(this, factory).get(MainActivityViewModel::class.java)
binding.rvParentExpenseDates.layoutManager = LinearLayoutManager(requireContext())
expensesViewModel.allExpenses.observe(viewLifecycleOwner){ expensesList ->
if (expensesList.isNotEmpty()){
binding.rvParentExpenseDates.adapter = expensesViewModel.uniqueDates.value?.let {
ParentDatesAdapter(it, expensesList) { expenseId ->
Toast.makeText(requireContext(), "Clicked expense with id: $expenseId", Toast.LENGTH_LONG).show()
}
}
binding.rvParentExpenseDates.visibility = View.VISIBLE
} else {
binding.rvParentExpenseDates.visibility = View.GONE
}
}
ExpenseEntity.kt
@Entity(tableName = "expense-table")
data class ExpenseEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
@ColumnInfo(name = "date-time")
val dateTime : Date?,
val date : Date?,
@ColumnInfo(name = "account-type")
val accountType : String = "",
val category : String = "",
val amount : Double = 0.0,
val currency : String = "",
val note : String = ""
)