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 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 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
< 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.
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.
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.