Topic is about Kotlin Recyclerview Button Android Tutorial With Example.
You will learn how to make a recycler view with button in it’s all rows in android using kotlin.
We will also learn how to handle button click for each row item in the recycler view.
First of all, see the following youtube video for the reference.
Step 1. New Project Information
Your first task is to make a new project in the android studio. While doing this, make sure that you select empty activity as the default one.
Also, set Kotlin as the source language for the entire android project.
Step 2. Gradle Changes
Let us make some changes in the build.gradle(Module : app) file. Add the following lines in build.gradle(Module : app) file
implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support:cardview-v7:28.0.0'
First line will import some important files so that we can use recycler view in our app.
Second line is for card view and it will enable us to use card view with recycler view.
Step 3. Writing Integer.xml
Now go to app->res->values directory and make a new file named Integer.xml
You need to write the below source code in Integer.xml
<?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>
This file help us to maintain the button settings inside the adapter file. You will understand usage of this file in the next steps.
Step 4. Making a XML and Model Class
Now navigate to app->res->layout directory and make a new file called rv_item.xml
You should write down the below source lines in rv_item.xml file.
<?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="wrap_content" android:orientation="vertical"> <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:id="@+id/card_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#fadcdc" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:orientation="horizontal"> <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:id="@+id/number" android:layout_width="wrap_content" android:layout_height="wrap_content" 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:id="@+id/plus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="20dp" android:text="Plus" android:textColor="#000" /> <Button android:id="@+id/minus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Minus" android:textColor="#000" /> </LinearLayout> </LinearLayout> </android.support.v7.widget.CardView> </LinearLayout>
This file is like a blue print for every row item of the recycler view. Adapter will use this file to create view for every row of recycler view.
Now create a new Kotlin class and give it a name like ReModel.kt
Below is the source code, you should add into the ReModel.kt file.
class ReModel { 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 } }
This file have two variables. An integer variable will represent the number of fruits.
A string variable will tell us about the name of the fruit. For both these variables, there are getter and setter methods, which will help us to maintain data.
Step 5. Creating An Adapter Class
Make a new Kotlin file with the name like ReAdapter.kt
ReAdapter.kt file should contain the below source code lines
import android.content.Context import android.support.v7.widget.RecyclerView import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.TextView /** * Created by Parsania Hardik on 29-Jun-17. */ class ReAdapter(private val ctx: Context) : RecyclerView.Adapter<ReAdapter.MyViewHolder>() { private val inflater: LayoutInflater init { inflater = LayoutInflater.from(ctx) } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReAdapter.MyViewHolder { val view = inflater.inflate(R.layout.rv_item, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: MyViewHolder, position: Int) { holder.tvFruit.setText(MainActivity.modelArrayList.get(position).getFruits()) holder.tvnumber.setText(MainActivity.modelArrayList.get(position).getNumbers().toString()) } override fun getItemCount(): Int { return MainActivity.modelArrayList.size } inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), View.OnClickListener { protected var btn_plus: Button protected var btn_minus: Button val tvFruit: TextView val tvnumber: TextView init { tvFruit = itemView.findViewById(R.id.animal) as TextView tvnumber = itemView.findViewById(R.id.number) as TextView btn_plus = itemView.findViewById(R.id.plus) as Button btn_minus = itemView.findViewById(R.id.minus) as Button btn_plus.setTag(R.integer.btn_plus_view, itemView) btn_minus.setTag(R.integer.btn_minus_view, itemView) btn_plus.setOnClickListener(this) btn_minus.setOnClickListener(this) } // onClick Listener for view override fun onClick(v: View) { if (v.id == btn_plus.id) { val tempview = btn_plus.getTag(R.integer.btn_plus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val number = Integer.parseInt(tv.text.toString()) + 1 tv.text = number.toString() MainActivity.modelArrayList.get(adapterPosition).setNumbers(number) } else if (v.id == btn_minus.id) { val tempview = btn_minus.getTag(R.integer.btn_minus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val number = Integer.parseInt(tv.text.toString()) - 1 tv.text = number.toString() MainActivity.modelArrayList.get(adapterPosition).setNumbers(number) } } } }
Reading above adapter
First of all, look at the onCreateViewHolder() method. This method is simply inflating the rv_item.xml file to create the look and feel of recycler view child items.
See at the method onBindViewHolder(), this method will set the text in two text views. One is the fruit name and another is the number. It will use modelArraylist for this purpose. We will create this modelArraylist in main activity.
Look at the below lines
btn_plus.setTag(R.integer.btn_plus_view, itemView) btn_minus.setTag(R.integer.btn_minus_view, itemView)
First line will set the tag to the plus button. It is using Integer.xml file’s member for this. This tag will help us to find appropriate row when the user clicks recycler view.
Similarly, second line is setting the tag to the minus button.
Now focus on the following lines
override fun onClick(v: View) { if (v.id == btn_plus.id) { val tempview = btn_plus.getTag(R.integer.btn_plus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val number = Integer.parseInt(tv.text.toString()) + 1 tv.text = number.toString() MainActivity.modelArrayList.get(adapterPosition).setNumbers(number) } else if (v.id == btn_minus.id) { val tempview = btn_minus.getTag(R.integer.btn_minus_view) as View val tv = tempview.findViewById(R.id.number) as TextView val number = Integer.parseInt(tv.text.toString()) - 1 tv.text = number.toString() MainActivity.modelArrayList.get(adapterPosition).setNumbers(number) } }
Compiler will run the above when the user clicks the reycler view. If user have clicked plus button then compiler go into the if statement.
Here, it will fetch the temporary view using the getTag() method. Using this temporary view, it will get the text view of clicked row item and will update it’s text.
If the user has clicked on minus button then compiler will go to the else statement.
It also has same logic, the only difference is that it will find the temporary view from the minus button.
Step 6. Main Activity Writings
In your activity_main.xml file, add the below codings
<?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"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:layout_marginTop="15dp"/> <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>
There is one recycler view and one button is present in the above file.
Now following is the source code for MainActivity.kt file.
import android.content.Intent import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v7.widget.LinearLayoutManager import android.support.v7.widget.RecyclerView import android.view.View import android.widget.Button import java.util.ArrayList class MainActivity : AppCompatActivity() { private var recyclerView: RecyclerView? = null private var customAdapter: ReAdapter? = null private var btnnext: Button? = null private val fruitlist = arrayOf("Apples", "Oranges", "Potatoes", "Tomatoes", "Grapes","Mangoes","Lichi", "strawberry") private val model: ArrayList<ReModel> get() { val list = ArrayList<ReModel>() for (i in 0..7) { val model = ReModel() 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) recyclerView = findViewById(R.id.recycler) as RecyclerView btnnext = findViewById(R.id.next) as Button modelArrayList = model customAdapter = ReAdapter(this) recyclerView!!.adapter = customAdapter recyclerView!!.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false) btnnext!!.setOnClickListener { val intent = Intent(this@MainActivity, NextActivity::class.java) startActivity(intent) } } companion object { lateinit var modelArrayList: ArrayList<ReModel> } }
See the below code first
private var recyclerView: RecyclerView? = null private var customAdapter: ReAdapter? = null private var btnnext: Button? = null private val fruitlist = arrayOf("Apples", "Oranges", "Potatoes", "Tomatoes", "Grapes","Mangoes","Lichi", "strawberry")
Compiler will create the objects of various classes like recycler view, ReAdapter and button.
An array called fruitlist contains the names of the various fruits.
Now focus on the following
private val model: ArrayList<ReModel> get() { val list = ArrayList<ReModel>() for (i in 0..7) { val model = ReModel() model.setNumbers(1) model.setFruits(fruitlist[i]) list.add(model) } return list }
Above code is creating a data source for recycler view. It will execute for loop and will set the number and fruit name in the each iteration.
Read the below code
modelArrayList = model customAdapter = ReAdapter(this) recyclerView!!.adapter = customAdapter recyclerView!!.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false) btnnext!!.setOnClickListener { val intent = Intent(this@MainActivity, NextActivity::class.java) startActivity(intent) }
First line using the model method to initialize the arraylist.
Then compiler will bind the adapter to the recycler view. When the user clicks the next button, compiler will open the Next activity. So let us create the next activity.
Step 7. Final Works
Make a new activity and give it a name like NextActivity.
You need to add the following source code in 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>
There is only one text view in this file.
You should write down the below source code in the NextActivity.kt file.
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..7) { val text = tv!!.text.toString() tv!!.text = text + MainActivity.modelArrayList[i].getFruits() + " -> " + MainActivity.modelArrayList[i].getNumbers() + "\n" } } }
Compiler will find the text view using id. Then it will create one for loop.
In this loop, it will set the name and it’s number into the text view.