Kotlin RecyclerView With Edittext in Android is the article of the day.
You will learn how to get and set text Values of edit text in the recycler view.
This tutorial will solve the problem like edit text loses content on scroll in recycler view.
After typing texts in the various edit texts of the recycler view, we will show all these edit text values in the new activity.
You will see how you can maintain the proper data structure through out the whole recycler view using model.
First of all, checkout the following video for output.
Step 1. Gradle Changes and New Project
First of all, make a fresh new project in your android studio. Here, take care about two things : set empty activity as the default and kotlin as the primary language.
Now, in your project, open build.gradle(Module:app) file and add the following two lines
implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support:cardview-v7:28.0.0'
These two lines are important to use recycler view and card view in our project because android do not have any UI widget for them.
We will be able to import necessary classes for using them in our Kotlin as well as XML file.
Step 2. Model and Layout File
Make a new Kotlin file with the name like EditModel.kt
You need to write down the below source snippet in EditModel.kt
public class EditModel { private var editTextValue: String? = null fun getEditTextValue(): String? { return editTextValue } fun setEditTextValue(editTextValue: String) { this.editTextValue = editTextValue } }
This class has one string variable editTextValue.
For this variable, I have also added getter and setter methods. This methods will help us to maintain the proper data in the recycler view.
Now, make a new XML file under app->res->layout directory. Name of this file should be rv_item.xml
rv_item.xml should contain the following writings
<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="wrap_content" android:paddingBottom="16dp" android:paddingLeft="16dp" android:paddingRight="16dp" android:paddingTop="16dp" android:background="@color/colorAccent" tools:context=".MainActivity"> <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="0dp" android:layout_marginRight="0dp" android:layout_marginTop="0dp" card_view:cardCornerRadius="4dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="80dp" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="12dp" android:textColor="#000" android:text="TextView:"/> <EditText android:layout_width="match_parent" android:layout_height="50dp" android:id="@+id/editid" android:layout_marginTop="10dp" android:paddingLeft="10dp" android:textColor="#000" android:text="hello" /> </LinearLayout> </android.support.v7.widget.CardView> </RelativeLayout>
We will use this file to create the look and feel of each row item of the recycler view.
This file has one card view and one edit text in it. So, every row will have one card view and one edit text.
Step 3. Creating An Adapter In Kotlin
Make a new Kotlin class with the name EditAdapter.kt and add the below code in it
import android.content.Context import android.support.v7.widget.RecyclerView import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.EditText import java.util.ArrayList /** * Created by Parsania Hardik on 17-Apr-18. */ class EditAdapter(ctx: Context, editModelArrayLists: ArrayList<EditModel>) : RecyclerView.Adapter<EditAdapter.MyViewHolder>() { private val inflater: LayoutInflater init { inflater = LayoutInflater.from(ctx) editModelArrayList = editModelArrayLists } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EditAdapter.MyViewHolder { val view = inflater.inflate(R.layout.rv_item, parent, false) return MyViewHolder(view) } override fun onBindViewHolder(holder: EditAdapter.MyViewHolder, position: Int) { holder.editText.setText(editModelArrayList[position].getEditTextValue()) Log.d("print", "yes") } override fun getItemCount(): Int { return editModelArrayList.size } inner class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { var editText: EditText init { editText = itemView.findViewById(R.id.editid) as EditText editText.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { } override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { editModelArrayList[adapterPosition].setEditTextValue(editText.text.toString()) } override fun afterTextChanged(editable: Editable) { } }) } } companion object { lateinit var editModelArrayList: ArrayList<EditModel> } }
Now look at the onCreateViewHolder() method. This method is inflating the rv_item.xml file. Thus, adapter can use the widgets placed in the rv_item.xml file.
Now focus on the onBindViewHolder() method. In this method, compiler is setting the text in the edit text.
For this, it is using editModelArrayList. This arralist made up with the objects of the EditModel class. Adapter is getting this editModelArrayList in it’s parameters from Main activity.
Now focus on the below source lines
editText.addTextChangedListener(object : TextWatcher { override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { } override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) { editModelArrayList[adapterPosition].setEditTextValue(editText.text.toString()) } override fun afterTextChanged(editable: Editable) { } })
Compiler will execute the onTextChanged() method when the user changes text of any edit text of the whole recycler view.
It will update the editModelArrayList based on the position of the row edited by the user. ( If first row then position is 0 )
Thus, this method is doing the data maintenance for us.
Step 4. Writing Main Code
Go to activity_main.xml file and add the below code
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn" android:text="Pass All EditText value to Next Activity"/> <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="15dp"/> </LinearLayout>
This file has two main UI widgets : A button and recycler view.
Now in the MainActivity.kt file, you need to add the following source snippet
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 btn: Button? = null private var recyclerView: RecyclerView? = null private var customAdapter: EditAdapter? = null lateinit var editModelArrayList: ArrayList<EditModel> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) recyclerView = findViewById(R.id.recycler) as RecyclerView btn = findViewById(R.id.btn) as Button editModelArrayList = populateList() customAdapter = EditAdapter(this, editModelArrayList) recyclerView!!.adapter = customAdapter recyclerView!!.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false) btn!!.setOnClickListener { val intent = Intent(this@MainActivity, NextActivity::class.java) startActivity(intent) } } private fun populateList(): ArrayList<EditModel> { val list = ArrayList<EditModel>() for (i in 0..7) { val editModel = EditModel() editModel.setEditTextValue(i.toString()) list.add(editModel) } return list } }
First of all, see the below
private var btn: Button? = null private var recyclerView: RecyclerView? = null private var customAdapter: EditAdapter? = null lateinit var editModelArrayList: ArrayList<EditModel>
Compiler will create the objects of the Button, Recycler View and EditAdapter classes.
Then an arraylist (editModelArrayList) will be created with the objects of the EditModel class.
Now read the following lines
editModelArrayList = populateList() customAdapter = EditAdapter(this, editModelArrayList) recyclerView!!.adapter = customAdapter recyclerView!!.layoutManager = LinearLayoutManager(applicationContext, LinearLayoutManager.VERTICAL, false)
Compiler will fill up the editModelArrayList using the populateList() method.
Then compiler will bind the adapter to the recycler view.
Now below is the coding lines for populateList() method.
private fun populateList(): ArrayList<EditModel> { val list = ArrayList<EditModel>() for (i in 0..7) { val editModel = EditModel() editModel.setEditTextValue(i.toString()) list.add(editModel) } return list }
Compiler will execute one for loop in this method. During the each iteration of this loop, it will create the object of the EditModel class.
Then it will set the edit text value for this object and then this object will be added to the array list.
Thus, we are making our data source in this method.
When the user clicks the button, compiler will open the NextActivity.
Step 5. Code for Next Activity
Make a new activity as the name like NextActivity.
Below should be the coding lines for activity_next.xml file.
<?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:textSize="20sp" android:id="@+id/tv"/> </RelativeLayout>
There is only one text view in this layout file.
You need to write down the below code in 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 until EditAdapter.editModelArrayList.size) { tv!!.text = tv!!.text.toString() + " " + EditAdapter.editModelArrayList.get(i).getEditTextValue() + System.getProperty( "line.separator" ) } } }
Here, compiler will execute the for loop. During this, it will set the edit text value inside a text view.
It will do this process one by one, so at the end of the loop, text view will have the text value of all the edit texts of the recycler view.
Download Kotlin RecyclerView With EditText
https://github.com/demonuts/Kotlin-RecyclerView-With-Edittext-Android-Get-Set-text-Value