I get error when I press button inside recycler view. My application is not crashing. I am trying to set a button in the recycler view and callingsetOnClickListener
inside onBindViewHolder
. Inside the holder.Button.setOnClickListener{}
I change the button text to notified
. But when I press a button the values of other button text in another list also changes. This is a listview of firestore documents. I have many documents that are uploaded into the recycler view. If I am getting the error how should I implement the button onclicklistener without this error.[![https://i.stack.imgur.com/S0Oxm.jpg][1]][1] [![enter image description here][2]][2]
/**This my activity for recycler view*/
package com.example.bloodbankcompany.recyclerview
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Adapter
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.bloodbankcompany.MyAdapter
import com.example.bloodbankcompany.R
import com.example.bloodbankcompany.User1
import com.example.bloodbankcompany.User2
import com.google.firebase.firestore.*
import java.lang.NullPointerException
class MainActivity2 : AppCompatActivity() {
private lateinit var recyclerView: RecyclerView
private lateinit var userArrayList: ArrayList<User2>
private lateinit var myAdapter: MyAdapter2
private val mFireStore = FirebaseFirestore.getInstance()
var db = FirebaseFirestore.getInstance()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
recyclerView= findViewById(R.id.recyclerview)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
userArrayList= arrayListOf()
myAdapter =MyAdapter2(userArrayList)
recyclerView.adapter = myAdapter
EventChangeListener()
}
private fun EventChangeListener() {
try {
mFireStore.collection("applicationForm").addSnapshotListener(object :
EventListener<QuerySnapshot> {
override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
if (error != null) {
Log.e("firestore error", error.message.toString())
}
try {
for (dc: DocumentChange in value?.documentChanges!!) {
if (dc.type == DocumentChange.Type.ADDED) {
userArrayList.add(dc.document.toObject(User2::class.java))
}
// Toast.makeText(applicationContext,userArrayList.toString(), Toast.LENGTH_SHORT).show()
}
} catch (e:NullPointerException){
}
myAdapter.notifyDataSetChanged()
}
})
} catch (e:NullPointerException){
}
}
}
/**
* This is my myAdapter activity for adapater*/
package com.example.bloodbankcompany.recyclerview
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.example.bloodbankcompany.R
import com.example.bloodbankcompany.RegisterActivity
import com.example.bloodbankcompany.User2
import com.google.firebase.firestore.FirebaseFirestore
import kotlinx.android.synthetic.main.list_item2.view.*
class MyAdapter2(private val userList: ArrayList<User2>): RecyclerView.Adapter<MyAdapter2.MyViewHolder>(){
var id: String = ""
private val mFireStore = FirebaseFirestore.getInstance()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter2.MyViewHolder {
val itemView = LayoutInflater.from(parent.context).inflate(R.layout.list_item2,parent,false)
return MyViewHolder(itemView)
}
override fun onBindViewHolder(holder: MyAdapter2.MyViewHolder, position: Int) {
val user:User2 = userList[position]
holder.name.text= user.name
holder.phone.text= user.phone
holder.address.text =user.address
holder.bloodGroup.text= user.bloodgroup
holder.id.text = user.id
//Setting onclicklistener to my adapter and starting intent
holder.button.setOnClickListener {
// holder.io = "kkj"
// holder.id.text = " "
holder.button.setText("notified")
// val context=holder.button.context
// val intent = Intent( context, RegisterActivity::class.java)
// context.startActivity(intent)
}
}
override fun getItemCount(): Int {
return userList.size
}
public class MyViewHolder(itemView : View): RecyclerView.ViewHolder(itemView){
val name : TextView = itemView.findViewById(R.id.tvfirstname1)
val phone :TextView= itemView.findViewById(R.id.tvphone11)
val address : TextView= itemView.findViewById(R.id.tvaddress1)
val bloodGroup: TextView =itemView.findViewById(R.id.tvbloodg1)
val id: TextView = itemView.findViewById(R.id.tvid)
var io: String? = ""
var button: Button = itemView.findViewById(R.id.btn_notify)
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
init {
itemView.btn_notify.setOnClickListener {
}
}
}
}
} ```
[1]: https://i.stack.imgur.com/S0Oxm.jpg
[2]: https://i.stack.imgur.com/BqDMf.jpg
2
Answers
create interface for
clickListener
in your adapter and set it inconstructor
and in
ViewHolder
setbind
your buttonand then set this code in
onBindViewHolder
finally when click on button you can action in
Activity or Fragment
example :
Simple Code, Without using Interface
Actually what I found is you were doing it the correct way, but you were using two
ViewHolder
classes there which is the cause of issue. Try to use the below code once and try again. Hope it works.