Save items of checked checkboxes displayed in recycler view in a list

Viewed 279

I manage to display the items stored in a room database in a recycler view with checkboxes and i want to store the checked items in a list, to store the checked items on a list I use setOnClickListener on the checkbox like the code below in adapter but the application stop when i click to display the list or even if the list displayed with success sometimes it stops when i click on the checkbox of an item (for information when i remove the listener the list is displayed well and I can click on the checkboxes and everything works well but the problem is when i add the listener to store the checked items).

    class Adapter (val selectedFluxs : MutableList<Flux>)  : RecyclerView.Adapter<Adapter.VH>(
) {
    class VH(itemView: View) : RecyclerView.ViewHolder(itemView){
        lateinit var feed : Flux
    }
    var allFluxs : List<Flux> = listOf()
    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val v = LayoutInflater
            .from(parent.getContext())
            .inflate(R.layout.item_layout, parent, false)
        val holder = VH( v )

        v.check.setOnClickListener( ) {
           // it as CheckBox
            if( v.check.isChecked ){
                selectedFluxs.add ( holder.feed )
            }else{
                selectedFluxs.remove( holder.feed )
            }
        }
        return holder
    }

    override fun getItemCount(): Int {
        return allFluxs.size
    }
    fun setFlux( allFlux : List<Flux> ) {
        this.allFluxs = allFlux
        notifyDataSetChanged()
    }
    override fun onBindViewHolder(holder: VH, position: Int) {
        holder.itemView.apply {
            Source.text = allFluxs[position].source
            Tag.text = allFluxs[position].tag
            Url.text = allFluxs[position].adr
           
            check.isChecked =
                holder.feed in selectedFluxs
        }
    }
}







 
2 Answers

It's too early to use ViewHolder views before instantiating the ViewHolder instance, so Move the code of the listener from onCreateViewHolder to onBindViewHolder

So, your class code should be:

class Adapter (val selectedFluxs : MutableList<Flux>)  : RecyclerView.Adapter<Adapter.VH>(
    ) {
    class VH(itemView: View) : RecyclerView.ViewHolder(itemView){
        lateinit var feed : Flux
    }
    var allFluxs : List<Flux> = listOf()


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
        val v = LayoutInflater
            .from(parent.getContext())
            .inflate(R.layout.item_layout, parent, false)
        val holder = VH( v )

        }
        return holder
    }

    override fun getItemCount(): Int {
        return allFluxs.size
    }
    fun setFlux( allFlux : List<Flux> ) {
        this.allFluxs = allFlux
        notifyDataSetChanged()
    }
    override fun onBindViewHolder(holder: VH, position: Int) {
        holder.itemView.apply {
            Source.text = allFluxs[position].source
            Tag.text = allFluxs[position].tag
            Url.text = allFluxs[position].adr
            setBackgroundColor(
                if (position % 2 == 0)
                    Color.argb(30,0,220,0)
                else
                    Color.argb(30,0,0,220)
            )
            check.isChecked =
                holder.feed in selectedFluxs
                
        
            holder.check.setOnClickListener( ) {
            // it as CheckBox
            if( v.check.isChecked ){
                selectedFluxs.add ( holder.feed )
            }else{
                selectedFluxs.remove( holder.feed )
            }
        }
    }
}

I solved the problem a minute after posting the question, in fact the problem is that I did not initialize the variable : lateinit var feed: Flux of the Holder with : holder.feed = allFluxs[position] in the onBindViewHolder method . i did that and it works .

Related