Android Kotlin ListView Button Tutorial With Example is covered in this article.
In this example, we will make a listview with button and textview in every child row of the listview.
You will learn how to manage clicklistener for every button.
There are some common problems like,
- You have clicked the button of first row but it affects last row.
- When you scroll down through the listview, click effect is gone
In this tutorial, we will solve above problems.
After following all the steps, you should have following output for kotlin listview button example
There are two buttons and one textview in every row of the listview. Textview will represent the counter(an integer number).
We will update the counter with two buttons – plus and minus.
Before you start
Make sure you are familiar with the model method to implement listview.
If you do not know about model structure for listview then read how to make model in listview example with kotlin.
When you need to put checkbox in listview then visit kotlin listview with checkbox tutorial.
Step 1. Model Class
Open a new class with name Model.kt
Source code for this class contains following lines.
/** * Created by hardik on 9/1/17. */ class Model { var number: Int = 0 var fruit: String? = null fun getNumbers(): Int { return number } fun setNumbers(number: Int) { this.number = number } fun getFruits(): String { return fruit.toString() } fun setFruits(fruit: String) { this.fruit = fruit } }
We will create various objects of model class and will set them in one arraylist.
This arraylist will give the data like name of the fruit and the quantity of the fruits for each row of listview.
Step 2. Creating row layout file
We need to create one layout resource file, which will represent the each row layout of the listview.
Make a file and give it a name lv_item.xml
Add below code in it.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="20dp"> <TextView android:id="@+id/animal" android:layout_width="130dp" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="animal" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="#000" android:textSize="20sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/number" android:layout_marginLeft="20dp" android:text="1" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#000" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="horizontal"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/plus" android:layout_marginLeft="20dp" android:text="Plus" android:textColor="#000" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/minus" android:text="Minus" android:textColor="#000" /> </LinearLayout> </LinearLayout>
Step 3: Integer Resource File
Now make one integer resource file named integer.xml
This file includes constant integer values with specific key names.
To create integer.xml file, right click on values folder -> New -> Value resource file
Following is the source code for this file.
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="btn_plus_view">1</integer> <integer name="btn_plus_pos">2</integer> <integer name="btn_minus_view">3</integer> <integer name="btn_minus_pos">4</integer> </resources>
Here, btn_plus_view, btn_plus_pos etc. are the keys and 1,2 are the values for their keys.
Step 4. Preparing Custom Adapter
Custom Adapter will send data to th listview about button names and textview’s value in string format.
Open a fresh new class with name CustomAdapter.kt
Source code should look like following
import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseAdapter import android.widget.Button import android.widget.TextView /** * Created by hardik on 9/1/17. */ class CustomAdapter(private val context: Context) : BaseAdapter() { override fun getViewTypeCount(): Int { return count } override fun getItemViewType(position: Int): Int { return position } override fun getCount(): Int { return MainActivity.modelArrayList.size } override fun getItem(position: Int): Any { return MainActivity.modelArrayList.get(position) } override fun getItemId(position: Int): Long { return 0 } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { var convertView = convertView val holder: ViewHolder if (convertView == null) { holder = ViewHolder() val inflater = context .getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater convertView = inflater.inflate(R.layout.lv_item, null, true) holder.tvFruit = convertView!!.findViewById(R.id.animal) as TextView holder.tvnumber = convertView.findViewById(R.id.number) as TextView holder.btn_plus = convertView.findViewById(R.id.plus) as Button holder.btn_minus = convertView.findViewById(R.id.minus) as Button convertView.tag = holder } else { // the getTag returns the viewHolder object set as a tag to the view holder = convertView.tag as ViewHolder } holder.tvFruit!!.setText(MainActivity.modelArrayList.get(position).getFruits()) holder.tvnumber!!.setText(MainActivity.modelArrayList.get(position).getNumbers().toString()) holder.btn_plus!!.setTag(R.integer.btn_plus_view, convertView) holder.btn_plus!!.setTag(R.integer.btn_plus_pos, position) holder.btn_plus!!.setOnClickListener { val tempview = holder.btn_plus!!.getTag(R.integer.btn_plus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val pos = holder.btn_plus!!.getTag(R.integer.btn_plus_pos) as Int val number = Integer.parseInt(tv.text.toString()) + 1 tv.text = number.toString() MainActivity.modelArrayList.get(pos).setNumbers(number) } holder.btn_minus!!.setTag(R.integer.btn_minus_view, convertView) holder.btn_minus!!.setTag(R.integer.btn_minus_pos, position) holder.btn_minus!!.setOnClickListener { val tempview = holder.btn_minus!!.getTag(R.integer.btn_minus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val pos = holder.btn_minus!!.getTag(R.integer.btn_minus_pos) as Int val number = Integer.parseInt(tv.text.toString()) - 1 tv.text = number.toString() MainActivity.modelArrayList.get(pos).setNumbers(number) } return convertView } private inner class ViewHolder { var btn_plus: Button? = null var btn_minus: Button? = null var tvFruit: TextView? = null internal var tvnumber: TextView? = null } }
For updating counter with plus and minus button clicks, we need to capture button of which row is clicked.
For this purpose, we will set tags to each button in every row of listview. Then we will retrieve position of clicked by getting those tags.
This is the main logic of this whole tutorial.
For setting tags, setTag() method is used and getTag() method will give access to clicked button.
Consider following code lines
holder.btn_minus!!.setTag(R.integer.btn_minus_view, convertView) holder.btn_minus!!.setTag(R.integer.btn_minus_pos, position)
With every minus button, view and position are tagged with unique key.
Now following code will get this tag.
val tempview = holder.btn_minus!!.getTag(R.integer.btn_minus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val pos = holder.btn_minus!!.getTag(R.integer.btn_minus_pos) as Int val number = Integer.parseInt(tv.text.toString()) - 1 tv.text = number.toString() MainActivity.modelArrayList.get(pos).setNumbers(number)
As you can see, first of all we will get view of whole row layout and we store it in the tempview variable.
Then, with the help of tempview, we will get the textview and will update it’s value.
We need to update the quantity of fruits with plus and minus button click. This is done by following line
MainActivity.modelArrayList.get(pos).setNumbers(number)
Here, modelArrayList is defined in the Main Activity and it’s access is defines as public, so we can use it in any class of whole application.
Step 5. Next Activity To Send Data
Prepare a new activity named NextActivity.
We will send data to this next activity.
It will generate two file : NextActivity.kt and activity_next.xml
Put below code into the NextActivity.kt
import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.widget.TextView class NextActivity : AppCompatActivity() { private var tv: TextView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_next) tv = findViewById(R.id.tv) as TextView for (i in 0..4) { val text = tv!!.text.toString() tv!!.text = text + MainActivity.modelArrayList.get(i).getFruits() + " -> " + MainActivity.modelArrayList.get(i).getNumbers() + "\n" } } }
Now add following into the activity_next.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/tv" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="#000" android:layout_marginTop="20dp" android:layout_marginLeft="20dp"/> </RelativeLayout>
Step 6. Changing Main Activity
There are some necessary changes needed to be done in MainActivity.kt class.
Replace your existing source code with below one.
import android.content.Intent import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.view.View import android.widget.Button import android.widget.ListView import java.util.ArrayList class MainActivity : AppCompatActivity() { private var lv: ListView? = null private var customAdapter: CustomAdapter? = null private var btnnext: Button? = null private val fruitlist = arrayOf("Apples", "Oranges", "Potatoes", "Tomatoes", "Grapes") private val model: ArrayList<Model> get() { val list = ArrayList<Model>() for (i in 0..4) { val model = Model() model.setNumbers(1) model.setFruits(fruitlist[i]) list.add(model) } return list } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) lv = findViewById(R.id.lv) as ListView btnnext = findViewById(R.id.next) as Button modelArrayList = model customAdapter = CustomAdapter(this) lv!!.adapter = customAdapter btnnext!!.setOnClickListener { val intent = Intent(this@MainActivity, NextActivity::class.java) startActivity(intent) } } companion object { lateinit var modelArrayList: ArrayList<Model> } }
Now change your activity_main.xml file’s code with below
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/lv"/> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="1" android:id="@+id/next" android:text="Next Activity"/> </LinearLayout> </LinearLayout>
So it was all the details about making kotlin listview button in android studio.
If you have any queries then comment it out, We will respond you quickly.
Do not forget to share DemoNut’s resources in your social media.
Download the Source code for Kotlin ListView Button Tutorial
[sociallocker]Download Kotlin ListView With Button[/sociallocker]