How to Add Views Dynamically and Store Data in Arraylist in Android?
Dynamic Views are created when we don’t want to have repeating XML code. In this article we will create a separate layout and inflate them inside a LinearLayout after that we will store the user data in an ArrayList as then display them as toast. A sample video is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Kotlin language.
Step by Step Implementation
Step 1: Create a new project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Kotlin as the programming language
Step 2: Add dependency inside build.gradle(app)
Add View Binding dependency inside the build.gradle(app) and click on the sync now button.
android {
..
buildFeatures {
viewBinding true
}
}
Step 3: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file. Notice that it has a Linear Layout with id parent_linear_layout which we will inflate to add our views.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" tools:context = ".MainActivity" > < TextView android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_margin = "15dp" android:text = "Programming Language List" android:textColor = "@color/black" android:textSize = "15sp" /> <!--This is the parent linear layout which we will inflate soon--> < LinearLayout android:id = "@+id/parent_linear_layout" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:orientation = "vertical" /> < com.google.android.material.button.MaterialButton android:id = "@+id/button_add" android:layout_width = "wrap_content" android:layout_height = "50dp" android:layout_marginLeft = "15dp" android:layout_marginTop = "10dp" android:drawableRight = "@drawable/ic_add" android:paddingLeft = "10dp" android:paddingRight = "10dp" android:text = "Add" android:textAllCaps = "false" android:textColor = "@color/white" /> < com.google.android.material.button.MaterialButton android:id = "@+id/button_submit_list" android:layout_width = "match_parent" android:layout_height = "50dp" android:layout_marginLeft = "15dp" android:layout_marginTop = "10dp" android:layout_marginRight = "15dp" android:paddingLeft = "10dp" android:paddingRight = "10dp" android:text = "Submit List" android:textAllCaps = "false" android:textColor = "@color/white" /> < com.google.android.material.button.MaterialButton android:id = "@+id/button_show_list" android:layout_width = "match_parent" android:layout_height = "50dp" android:layout_marginLeft = "15dp" android:layout_marginTop = "10dp" android:layout_marginRight = "15dp" android:paddingLeft = "10dp" android:paddingRight = "10dp" android:text = "Show List Data" android:textAllCaps = "false" android:textColor = "@color/white" /> </ LinearLayout > |
Step 4: Create a new layout
Create a new layout named row_add_language.xml. This is the separate layout that we will inflate inside the Linear Layout with id parent_linear_layout.
XML
<? xml version = "1.0" encoding = "utf-8" ?> < androidx.constraintlayout.widget.ConstraintLayout android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_margin = "10dp" > < EditText android:id = "@+id/et_name" android:layout_width = "200dp" android:layout_height = "50dp" android:hint = "Enter language" app:layout_constraintLeft_toLeftOf = "parent" app:layout_constraintTop_toTopOf = "parent" /> < Spinner android:id = "@+id/exp_spinner" android:layout_width = "100dp" android:layout_height = "50dp" android:layout_marginStart = "20dp" android:entries = "@array/experience" app:layout_constraintLeft_toRightOf = "@id/et_name" app:layout_constraintTop_toTopOf = "parent" /> </ androidx.constraintlayout.widget.ConstraintLayout > |
Step 5: Add the entries item in string.xml that we have used in Spinner
XML
< string-array name = "experience" > < item >Exp</ item > < item >1 Year</ item > < item >2 Year</ item > < item >3 Year</ item > < item >4 Year</ item > </ string-array > |
Step 6: Create a new Kotlin class
Create a new Kotlin class Language.kt. This is the generic class which we will use for Arraylist to Store data.
Kotlin
class Language( var name: String = "" , var exp: String = "" ) { } |
Step 7: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.widget.EditText import android.widget.Spinner import android.widget.Toast import androidx.appcompat.app.AppCompatActivity // Provide your package name here import com.example.addviewsdynamically.databinding.ActivityMainBinding class MainActivity : AppCompatActivity() { // initiate viewBinding private var _binding: ActivityMainBinding? = null private val binding get() = _binding!! // create an arraylist in which // we will store user data private var languageList = ArrayList<Language>() override fun onCreate(savedInstanceState: Bundle?) { super .onCreate(savedInstanceState) _binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) // This addButton is used to add a new view // in the parent linear layout binding.buttonAdd.setOnClickListener { addNewView() } // This Submit Button is used to store all the // data entered by user in arraylist binding.buttonSubmitList.setOnClickListener { saveData() } // This Show button is used to show data // stored in the arraylist. binding.buttonShowList.setOnClickListener { showData() } } // This function is called after // user clicks on addButton private fun addNewView() { // this method inflates the single item layout // inside the parent linear layout val inflater = LayoutInflater.from( this ).inflate(R.layout.row_add_language, null ) binding.parentLinearLayout.addView(inflater, binding.parentLinearLayout.childCount) } // This function is called after user // clicks on Submit Button private fun saveData() { languageList.clear() // this counts the no of child layout // inside the parent Linear layout val count = binding.parentLinearLayout.childCount var v: View? for (i in 0 until count) { v = binding.parentLinearLayout.getChildAt(i) val languageName: EditText = v.findViewById(R.id.et_name) val experience: Spinner = v.findViewById(R.id.exp_spinner) // create an object of Language class val language = Language() language.name = languageName.text.toString() language.exp = experience.selectedItem as String // add the data to arraylist languageList.add(language) } } // This function is called after user // clicks on Show List data button private fun showData() { val count = binding.parentLinearLayout.childCount for (i in 0 until count) { Toast.makeText( this , "Language at $i is ${languageList[i].name} and experience is ${languageList[i].exp} " , Toast.LENGTH_SHORT).show() } } override fun onDestroy() { super .onDestroy() _binding = null } } |
Output:
Github repo here.