How to get the selected item from ListView in Kotlin?

13.9k views Asked by At

Code Sample:

package tech.kapoor.listviewdemo

import android.content.Context
import android.graphics.Color
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.ListView
import android.widget.TextView
import android.widget.AdapterView


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val listView = findViewById<ListView>(R.id.main_listview)
        var redColor = Color.parseColor("#FF0000")

        listView.setBackgroundColor(redColor)
        listView.adapter = CustomAdapter(this)
    }

    private class CustomAdapter(context: Context): BaseAdapter() {

        private val mContext: Context

        init {
            mContext = context
        }

        override fun getCount(): Int {
            return 80
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getItem(position: Int): Any {
            return position
        }

        override fun getView(position: Int, view: View?, viewGroup: ViewGroup?): View {
            val textView = TextView(mContext)
            textView.text = "Here comes the !!"
            return textView
        }
    }
}

I'm trying to understand list view instead of recycler view to understand basics first. Anybody knows how we get the selected row id/index value on selection or onclick and also how to perform some action on selection of a specific row in kotlin?

3

There are 3 answers

4
AndiM On BEST ANSWER

To populate listview you must have dataset. Dataset may be any list of either datatypes like Strings or you can use list of model class. Something like this:

This is my simple list of dataset which I will use in ListView:

val data = ArrayList<TopicDTO>()
data.add(TopicDTO("1", "Info 1", true))
data.add(TopicDTO("2", "Info 2", false))
data.add(TopicDTO("3", "Info 3", true))
data.add(TopicDTO("4", "Info 4", false))

I have created one model class named TopicDTO which contains id,title and its status.

Now let's populate this into ListView:

 list.adapter = ButtonListAdapter(baseContext, data)

Here is a simple adapter:

class ButtonListAdapter(//Class for rendering each ListItem

        private val context: Context, private val rowItems: List<TopicDTO>) : BaseAdapter() {

    override fun getCount(): Int {
        return rowItems.size
    }

    override fun getItem(position: Int): Any {
        return rowItems[position]
    }

    override fun getItemId(position: Int): Long {
        return rowItems.indexOf(getItem(position)).toLong()
    }


    private inner class ViewHolder {
        internal var main_text: TextView? = null //Display Name
        internal var subtitle: TextView? = null  //Display Description
        internal var can_view_you_online: Button? = null   //Button to set and display status of CanViewYouOnline flag of the class

    }

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        var convertView = convertView
        var holder: ViewHolder? = null


        val mInflater = context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE) as LayoutInflater

        holder = ViewHolder()


        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.main_lp_view_item, null)

            holder.main_text = convertView!!.findViewById(R.id.main_lp_text) as TextView
            holder.subtitle = convertView.findViewById(R.id.main_lp_subtitle) as TextView
            holder.can_view_you_online = convertView.findViewById(R.id.can_view_you_online) as Button

            convertView.tag = holder

        } else {
            holder = convertView.tag as ViewHolder
        }

        val rowItem = rowItems[position]

        val main_text: String
        val subtitle: String


        holder.main_text!!.text = rowItem.info
        holder.subtitle!!.text = rowItem.info

        if (rowItem.canViewYouOnline) {
            holder.can_view_you_online!!.setBackgroundColor(context.resources.getColor(R.color.colorPrimary))
        } else {
            holder.can_view_you_online!!.setBackgroundColor(context.resources.getColor(R.color.colorAccent))
        }


        holder.can_view_you_online!!.setOnClickListener(object : View.OnClickListener {
            internal var buttonClickFlag: Boolean = false


            override fun onClick(v: View) {           //The Onclick function allows one to click the button on the list item and set/reset the canViewYouOnline flag. It is working fine.

            }
        })


        return convertView

    }


}

Now you can get your selected item like this:

list.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            // This is your listview's selected item
            val item = parent.getItemAtPosition(position) as TopicDTO
        }

Hope you understands this.

1
Gabriele Mariotti On

You can use inside the getView() method something like:

view.setOnClickListener(object : View.OnClickListener {
    override fun onClick(v: View?) {
        //use getItem(position) to get the item
    }
})

or using the lambda:

view.setOnClickListener({ v -> //use theItem(position) })

Just a tip:

I'm trying to understand list view instead of recycler view to understand basics first.

In my opinion in your projects you will use RecyclerView in 99% of the cases.

0
Richard Kamere On

add OnItemClickListener in you oncreate()

    listView.setOnItemClickListener{ parent, view, position, id -&gt;
        Toast.makeText(this, "You Clicked:"+" "+position,Toast.LENGTH_SHORT).show()
    }

enter image description here

Add the array of Items in your CustomAdapter class.

class CustomAdptor(private val context: Activity): BaseAdapter() {
//Array of fruits names
var names = arrayOf("Apple", "Strawberry", "Pomegranates", "Oranges", "Watermelon", "Bananas", "Kiwi", "Tomato", "Grapes")
//Array of fruits desc
var desc = arrayOf("Malus Domestica", "Fragaria Ananassa ", "Punica Granatum", "Citrus Sinensis", "Citrullus Vulgaris", "Musa Acuminata", "Actinidia Deliciosa", "Solanum Lycopersicum", "Vitis vinifera")

//Array of fruits images
var image = intArrayOf(R.drawable.apple, R.drawable.strawberry, R.drawable.pomegranates, R.drawable.oranges, R.drawable.watermelon, R.drawable.banana, R.drawable.kiwi, R.drawable.tomato, R.drawable.grapes)
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
    val inflater = context.layoutInflater
    val view1 = inflater.inflate(R.layout.row_data,null)
    val fimage = view1.findViewById(R.id.fimageView)
    var fName = view1.findViewById(R.id.fName)
    var fDesc = view1.findViewById(R.id.fDesc)
    fimage.setImageResource(image[p0])
    fName.setText(names[p0])
    fDesc.setText(desc[p0])
    return view1
}

override fun getItem(p0: Int): Any {
    return image[p0]
}

override fun getItemId(p0: Int): Long {
    return p0.toLong()
}

override fun getCount(): Int {
    return image.size
}

}

You can find the whole tutorial at: listview with onItemClickListener using kotlin