Introduction
This code demonstrates how to manage a list of items in a RecyclerView using Kotlin in an Android application. The example showcases adding and removing items dynamically. A button click triggers the addition of a new item ("Donkey") to the list displayed by the RecyclerView. Clicking on the delete icon next to each item in the list removes it.
Breakdown
The code consists of three parts:
MainActivity.kt: This file defines the main activity of the application. It initializes the UI components (button and RecyclerView), creates a list of animals (data source), sets up the RecyclerView layout manager (GridLayoutManager), and creates an adapter to bind the data to the RecyclerView. It also implements the logic for adding a new item to the list when the button is clicked.
RecyclerViewAdapter.kt: This file defines the adapter class for the RecyclerView. It holds the data source (list of animals) and inflates a custom layout (custom_view.xml) for each item. It binds the animal name to the TextView and handles the click event on the delete icon to remove the corresponding item from the list and update the RecyclerView.
XML Layouts: There are two layout files:
- activity_main.xml: This defines the main layout of the activity containing the button and the RecyclerView.
- custom_view.xml: This defines the layout for each item displayed in the RecyclerView. It includes a TextView to display the animal name and an ImageView representing the delete icon.
Summary
This example provides a basic understanding of how to manage a dynamic list of items in an Android application using RecyclerView and Kotlin. The code demonstrates how to add and remove items from the list, update the adapter to reflect changes, and notify the RecyclerView to refresh its view.
package com.cfsuman.kotlintutorials
import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
class MainActivity : AppCompatActivity() {
private lateinit var context:MainActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get the context
context = this
// Get the widgets reference from XML layout
val button = findViewById<Button>(R.id.button)
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
// initialize a mutable list of animals
val animals = mutableListOf(
"Aardvark", "Albatross", "Alligator",
"Alpaca", "Ant", "Anteater",
"Barracuda", "Bear"
)
// initialize grid layout manager
GridLayoutManager(
context, // context
2, // span count
RecyclerView.VERTICAL, // orientation
false // reverse layout
).apply {
// specify the layout manager for recycler view
recyclerView.layoutManager = this
}
// finally, data bind the recycler view with adapter
val adapter = RecyclerViewAdapter(animals).apply {
recyclerView.adapter = this
}
// add an item to recycler view
button.setOnClickListener {
it.isEnabled = false
// add an item at the end of list
animals.add("Donkey")
adapter.notifyItemInserted(animals.size - 1)
recyclerView.scrollToPosition(animals.size - 1)
}
}
}
package com.cfsuman.kotlintutorials
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
class RecyclerViewAdapter(private val animals: MutableList<String>)
: RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup, viewType: Int): ViewHolder {
// inflate the custom view from xml layout file
val view: View = LayoutInflater.from(parent.context)
.inflate(R.layout.custom_view,parent,false)
// return the view holder
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
// display the current animal
holder.animal.text = animals[position]
// remove the item from recycler view
holder.remove.setOnClickListener {
animals.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position,animals.size)
}
}
override fun getItemCount(): Int {
// number of items in the data set held by the adapter
return animals.size
}
class ViewHolder(itemView: View)
: RecyclerView.ViewHolder(itemView){
val animal: TextView = itemView.findViewById(R.id.tvAnimal)
val remove: ImageView = itemView.findViewById(R.id.ivDelete)
}
// this two methods useful for avoiding duplicate item
override fun getItemId(position: Int): Long {
return position.toLong()
}
override fun getItemViewType(position: Int): Int {
return position
}
}
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rootLayout"
android:background="#DCDCDC">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:text="Add Item : Donkey"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button">
</androidx.recyclerview.widget.RecyclerView>
</androidx.constraintlayout.widget.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#F5F5F5"
app:cardCornerRadius="8dp"
app:cardElevation="4dp"
app:cardMaxElevation="6dp"
app:contentPadding="16dp"
android:layout_margin="6dp" >
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvAnimal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/ivDelete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/ivDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="12dp"
android:src="@drawable/ic_action_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
- android kotlin - ImageView tint programmatically
- android kotlin - ImageView set image from Uri
- android kotlin - Get battery capacity programmatically
- android kotlin - Repeat a task periodically
- android kotlin - Do a task after a delay
- android kotlin - Detect screen orientation change
- android kotlin - Get screen orientation programmatically
- android kotlin - RecyclerView animation
- android kotlin - RecyclerView smooth scroll
- android kotlin - RecyclerView horizontal
- android kotlin - RecyclerView divider line
- android kotlin - RecyclerView GridLayoutManager example
- android kotlin - RecyclerView StaggeredGridLayoutManager example
- android kotlin - Canvas draw multiline text
- android kotlin - Canvas center text