Reputation: 535
I'm having trouble with deleting data from my Firestore collection when the user clicks a delete button in a recyclerview. I can delete it from the recyclerview without any problems, but I'm having trouble to make the connection between the adapter, the viewmodel and the repository that handles Firestore operations.
In my adapter, I remove the item the user clicked on from the recyclerview:
class ArticleAdapter : RecyclerView.Adapter<ArticleAdapter.ViewHolder>() {
var data = mutableListOf<Product>()
set(value) {
field = value
notifyDataSetChanged()
}
override fun getItemCount() = data.size
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = data[position]
holder.bind(item)
holder.deleteButton.setOnClickListener {
data.removeAt(position)
notifyDataSetChanged()
}
} ...
The recyclerview is populated after a query to the Firestore collection in my viewmodel:
class ArticleViewModel(private val repository: ProductRepository) : ViewModel() {
var savedProducts: MutableLiveData<MutableList<Product>> = MutableLiveData<MutableList<Product>>()
init {
savedProducts = getProducts()
}
fun getProducts(): MutableLiveData<MutableList<Product>> {
repository.getProducts().addSnapshotListener(EventListener<QuerySnapshot> { value, e ->
if (e != null) {
savedProducts.value = null
return@EventListener
}
val savedProductsList: MutableList<Product> = mutableListOf()
for (doc in value!!) {
val item = doc.toObject(Product::class.java)
item.id = doc.id
savedProductsList.add(item)
}
savedProductsList.sortBy { i -> i.productName }
savedProducts.value = savedProductsList
})
return savedProducts
} }
In my Fragment, I'm then observing any changes that might happen to savedProducts:
class ArticleOverviewFragment : Fragment(), KodeinAware {
override val kodein: Kodein by kodein()
private val factory: ArticleViewModelFactory by instance()
private lateinit var viewModel: ArticleViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding: FragmentArticleOverviewBinding =
DataBindingUtil.inflate(inflater, R.layout.fragment_article_overview, container, false)
viewModel = ViewModelProviders.of(this, factory).get(ArticleViewModel::class.java)
binding.viewModel = viewModel
val adapter = ArticleAdapter()
binding.recyclerViewGoods.adapter = adapter
viewModel.savedProducts.observe(viewLifecycleOwner, Observer {
it?.let {
adapter.data = it
}
})
...
} }
Is there a way that I can observe/save the ID of the deleted item in my adapter and "transfer" that ID from the adapter to the UI where I call a function declared in the viewmodel whenever that field holding the ID is populated? Or should I directly access the viewmodel from the adapter? Somehow, that feels kinda wrong...
Upvotes: 1
Views: 5347
Reputation: 1347
Declare one local variable
var removedPosition : Int ? = null
then update this variable into onClick event of deleteButton
holder.deleteButton.setOnClickListener {
data.removeAt(position)
removedPosition = position
notifyDataSetChanged()
}
Please make one method in Adapter (ArticleAdapter
)
fun getRemoveItemPosition() : Int {
var position = removedPosition
return position;
}
which return the position of removed Item and call that method in UI(ArticleOverviewFragment
) where you will require to get position of removed item from recyclerview
var removedItemPosition = adapter.getRemoveItemPosition()
Now you will get value of remove item Position using variable called removedItemPosition
ArticleViewModel
) to delete particular item in firestore collection.
Upvotes: 4