Home > Software engineering >  Recyclerview to not update when activity containing it is opened?
Recyclerview to not update when activity containing it is opened?

Time:07-10

IS it possible for a recyclerview to not update when the activity is opened, but will update if reopened?

    db = FirebaseFirestore.getInstance()
    db.collection("Helpers")
        .whereEqualTo("helperReady", true)
        .whereEqualTo("state", "Online")
        .addSnapshotListener(object : EventListener<QuerySnapshot> {
            override fun onEvent(value: QuerySnapshot?, error: FirebaseFirestoreException?) {
                if (error != null) {
                    Log.d("Firestore Error: ", error.message.toString())
                    return
                }
                newArrayList.clear()
                for (dc: DocumentChange in value?.documentChanges!!) {
                    val currentUser = dc.document.toObject(HelperList::class.java)
                    if (dc.type == DocumentChange.Type.ADDED) {
                        if (auth.currentUser?.uid != currentUser?.userID) {
                            newArrayList.add(dc.document.toObject(HelperList::class.java))
                            newArrayList.sortByDescending {
                                it.rating
                            }
                        }
                    }

                }
                helperAdapter.notifyDataSetChanged()
            }
        })

Adapter:

class HelperAdapter(private val context: Context, private val helperList: ArrayList<HelperList>) : RecyclerView.Adapter<HelperAdapter.MyViewHolder>(){

private  lateinit var mListener: onItemClickListener

interface onItemClickListener{

    fun onItemClick(position: Int)

}

fun setOnItemClickListener(listener:onItemClickListener){

    mListener = listener

}


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

    val helperView = LayoutInflater.from(parent.context).inflate(R.layout.helpers_list_view, parent, false)
    return MyViewHolder(helperView, mListener)

}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

    val currentHelper = helperList[position]

    var delimiter = " "
    var firstName = currentHelper.helperName!!.substringBefore(delimiter)

    holder.helperName.text = firstName
    holder.helperBio.text = currentHelper.helperBio
    holder.helperRating.text = currentHelper.rating

    Glide.with(context).load(currentHelper.profileImage).into(holder.helperImage)

}

override fun getItemCount(): Int {

    return helperList.size
}

class MyViewHolder(itemView: View, listener: onItemClickListener) : RecyclerView.ViewHolder(itemView){

    val helperImage: CircleImageView = itemView.findViewById(R.id.helper_image)
    val helperName: TextView = itemView.findViewById(R.id.helper_name)
    val helperBio: TextView = itemView.findViewById(R.id.helper_bio)
    val helperRating: TextView = itemView.findViewById(R.id.helper_rating)

    init{

        itemView.setOnClickListener {

            listener.onItemClick(adapterPosition)

        }

    }

}

}

Array List:

data class HelperList(var helperName: String ?= null, var helperBio: String?=null, var helperPay: String ?=null, var helperSkills: String ?=null,
                   var helperNumber: String ?=null, var profileImage: String ?= null, var rating: String ?= null,
                    val userID: String, var tokenID: String ?= null){
constructor():this ("","", "", "", "", "", "", "", "")

}

This code updates the list but everytime a data changes, the list goes completely blank and will only show the updated item, when reopened it shows the item with the rest of the list. I want it to stay the way it is and the update to only show if the activity is reopened. Any help is appreciated.

CodePudding user response:

Edit: This is all on the assumption that newArrayList is the list used by the RecyclerView to display data.

Let's check your code.

You are updating the list as it is being changed. If we look at your code, you are listening to data changes in firebase

.addSnapshotListener

This means that whenever data changes in the database, your code will trigger.

In your code, you are then doing this

newArrayList.clear()

which basically clears the data in the list.

After that, you check if this event is true if (dc.type == DocumentChange.Type.ADDED), so you only add a newly added item in the now empty list. After all this, you then triger helperAdapter.notifyDataSetChanged() so the recyclerView updates with only the now one item size list.

Not sure if it will be the perfect approach, but you can remove the call to newArrayList.clear(), and then your list will update in real time without clearing everything currently in it.

If you want to make it even better, you should separate the data updating from the recyclerView update. Ideally, you should create a function in your class to set the new list of items.

This way, you can even check before calling the method to set the new items if the list is empty, and only set new data if it is empty by calling rvAdapter.itemCount.

Code for the recyclerViewAdapter

private var dataList: MutableList<MyData> = mutableListOf()

//for setting all the data when list is empty.
fun setItems(newItemsList : List<MyData>){
dataList.clear()
dataList.addAll(newItemsList)
notifyDataSetChanged()
}
//for only adding items to an existing list.
fun addItems(newItemsList : List<MyData){
//here maybe do some logic if your data is sorted and you don't want to break it
val lastIndex = dataList.lastIndex
dataList.addAll(lastIndex,newItemsList)
notifyItemRangeInserted(lastIndex, newItemsList.size)
}

Then listen in the activity/fragment to data changes, and call the corresponding function.

  • Related