Reputation: 175
I have a list of categories and i want to show the amount of items in each category. Using Room with MVVM architecture basically i want to use simple query in my adapter, to return its value (amount of items)
DAO
@Query("SELECT COUNT(id) FROM items WHERE listId=:listID")
suspend fun countItems(listID: Long):Int
Repo
suspend fun countItems(id: Long): Int{
return itemsDao.countItems(id)
}
Adapter
class ListsAdapter internal constructor(
context: Context
) : RecyclerView.Adapter<ListsAdapter.ListViewHolder>() {
private val inflater: LayoutInflater = LayoutInflater.from(context)
private var lists = mutableListOf<ListItem>()
inner class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
val listName: TextView = itemView.findViewById(R.id.single_list_name)
val listIcon: ImageView = itemView.findViewById(R.id.single_list_icon)
val wAmount: TextView = itemView.findViewById(R.id.single_list_amount)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListsAdapter.ListViewHolder {
val itemView = inflater.inflate(R.layout.single_list, parent, false)
return ListViewHolder(itemView)
}
override fun getItemCount() = lists.size
override fun onBindViewHolder(holder: ListsAdapter.ListViewHolder, position: Int) {
val current = lists[position]
holder.listName.text = current.name
// holder.wAmount.text =
holder.itemView.setOnClickListener {
val bundle = bundleOf("list_id" to current.id,"list_name" to current.name)
holder.itemView.findNavController().navigate(R.id.action_listsFragment_to_nav_items_list, bundle)
}
}
internal fun setLists(lists: List<ListItem>) {
this.lists = lists.toMutableList()
notifyDataSetChanged()
}
internal fun listToDelete(viewHolder: RecyclerView.ViewHolder) : ListItem{
val position = viewHolder.adapterPosition
return lists[position]
}
internal fun removeList(viewHolder: RecyclerView.ViewHolder){
lists.removeAt(viewHolder.adapterPosition)
notifyItemRemoved(viewHolder.adapterPosition)
}
}
Should it be done over ViewModel, but in that case it has to be passed to adapter? Or maybe there is better (cleaner) way to do it? Any help is appreciated. Thanks
Upvotes: 2
Views: 1240
Reputation: 855
Adapters shouldn't be responsible for loading data from storage. The clean way to do it is to access the repo in your ViewModel
, then pass the data to your Adapter
. This also gives you the benefit of being able to handle errors in a straightforward way, as it would be easy to update the layout containing Adapter
easily, unlike the spaghetti you'll need to do this from the adapter, in the addition to being a wrong design of course.
Another step would be to introduce a more layered architecture,like Uncle Bob's clean architecture
Upvotes: 3