Search code examples
androidkotlincustom-adapterandroid-checkbox

How to keep track of my checked CheckBoxes in a Custom Adapter?


I'm trying to find a way to keep track of all of my checked items within the ListView from the CheckBoxes.

I'm currently creating my custom adapter to handle everything but being able to keep track of all of my checked items so that I can later delete the checked items via a button press.

I'm not sure how to quite handle it. I've spent a few hours Googling on how to do it but most of it uses Java and I'm not sure on how to properly translate it's usage into Kotlin or even if it'd be applicable for my android app. If anyone could help me, it'd be greatly appreciated

DSArrayAdapter.kt - My Custom Array Adapter:

class DSArrayAdapter(context: Context, resource: Int, list: ArrayList<Contacts>) : ArrayAdapter<Contacts>(context, resource, list) {

    private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

    override fun getView(position: Int, convertView: View?, parent: ViewGroup) : View {
        val rowView = inflater.inflate(R.layout.activity_listview, null)
        val item_name = rowView.findViewById<TextView>(R.id.contact_name)
        val item_checkbox = rowView.findViewById<CheckBox>(R.id.checked)

        item_name.setText(getItem(position)?.cname.toString())

        item_checkbox.setOnClickListener(View.OnClickListener{
            val contact = getItem(position) as Contacts
            contact.cchecked = !contact.cchecked
            item_checkbox.isChecked = contact.cchecked
    })
        })

        return rowView
    }
}

Contacts.kt - My Class to hold properties of my contacts entries:

class Contacts(val cname: String, val cphone: Int, val cchecked: Boolean) {

}

Solution

  • It seems the object Contacts already have a field to track if the item is checked or not. So, you can use as follows:

    First, make cchecked variable. This way, it can be changed.

    // cchecked must be var so you can change between checked/unchecked
    class Contacts(val cname: String, val cphone: Int, var cchecked: Boolean) {
    }
    

    Then, in the adapter:

    class DSArrayAdapter(context: Context, resource: Int, list: ArrayList<Contacts>) : ArrayAdapter<Contacts>(context, resource, list) {
    
        private val inflater: LayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    
        override fun getView(position: Int, convertView: View?, parent: ViewGroup) : View {
    
            val rowView = inflater.inflate(R.layout.activity_listview, null)
            val item_name = rowView.findViewById<TextView>(R.id.contact_name)
            val item_checkbox = rowView.findViewById<CheckBox>(R.id.checked)
    
            val contact = getItem(position) as Contacts
    
            // Set text
            item_name.setText(contact.cname)
    
            // Set checkbox state
            item_checkbox.isChecked = contact.cchecked
    
            // If does not have a click listener yet, set one.
            // View will be re-used. So, you don't need to set a listener everytime
            if(!item_checkbox.hasOnClickListeners()) {
                item_checkbox.setOnClickListener {
                    // Get the old state
                    val contact = getItem(position) as Contacts
    
                    // Invert the old state in the contact
                    contact.cchecked = !contact.cchecked
    
                    // Apply the new state to the checkbox
                    item_checkbox.isChecked = contact.cchecked
                }
            }
            return rowView
        }
    }