I'm encountering an issue in my Android application where the categories displayed in a ChipGroup are not updating correctly after adding a new category. Here's the scenario:
- I have a ChipGroup that dynamically populates chips representing different categories.
- Categories are fetched from a Room database and observed for changes.
- I have two tabs: one for Income Transactions and one for Expense Transactions.
- Each tab should display categories specific to its type (income or expense).
- When a new category is added, the ChipGroup should update to display the new category along with the existing ones. However, after adding a new category, the ChipGroup sometimes displays categories from the wrong tab. For example, adding a category in the Expense tab might result in the ChipGroup showing categories from the Income tab instead of the updated list with the new category.
I'm having trouble identifying the cause of this issue, and I'm unsure how to reproduce it consistently.
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val tabLayout = view.findViewById<TabLayout>(R.id.transactionTabLayout)
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
currentTab = tab?.text.toString().lowercase()
categoryVM.getCategoriesByType(currentTab).observe(viewLifecycleOwner) { categories ->
populateChips(categories)
}
}
override fun onTabReselected(tab: TabLayout.Tab?) {
// Handle tab reselect
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
// Handle tab unselect
}
})
}
private fun populateChips(categories: List<Category>) {
val chipGroup = view?.findViewById<ChipGroup>(R.id.chipGroupCategories)
chipGroup?.removeAllViews()
// ...
createButton.setOnClickListener {
val categoryName = editText.text.toString().trim()
if (categoryName.isNotEmpty()) {
categoryVM.isCategoryNameUnique(categoryName, currentTab) { isUnique ->
if (!isUnique) textInputLayout.error = "Category already exists"
else {
// Category name is unique, proceed with adding the category
categoryVM.addCategory(
categoryName,
if (iconAdapter.getSelectedIcon() == R.drawable.ic_null_line) null else iconAdapter.getSelectedIcon(),
currentTab
)
alertDialog.dismiss()
}
}
}
}
}
// CategoriesViewModel
fun getCategoriesByType(type: String) = categoryRepository.getCategoriesByType(type).asLiveData(viewModelScope.coroutineContext)
fun addCategory(categoryName: String, categoryIconId: Int?, type: String) = viewModelScope.launch {
val categoryObject = Category(name = categoryName, iconId = categoryIconId, type = type)
categoryRepository.insertCategory(categoryObject)
}
// CategoryRepository
suspend fun insertCategory(category: Category) {
database.categoryDao().insertCategory(category)
}
fun getCategoriesByType(type: String) = database.categoryDao().getCategoriesByType(type)
// CategoryDao
@Query("SELECT * FROM categories WHERE type = :type")
fun getCategoriesByType(type: String): Flow<List<Category>>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCategory(category: Category)