How to Create Options Menu for RecyclerView in Android using Kotlin?

24 Mar, 2021
RecyclerView is a ViewGroup added to the android studio as a successor of the GridView and ListView. It is an improvement on both of them and can be found in the latest v-7 support packages. It has been created to make possible construction of any lists with XML layouts as an item that can be customized vastly while improving the efficiency of ListViews and GridViews. This improvement is achieved by recycling the views which are out of the visibility of the user. For example, if a user scrolled down to a position where items 4 and 5 are visible; items 1, 2, and 3 would be cleared from the memory to reduce memory consumption. In this article, we will explain how to use the Options menu in each item of the RecyclerView. Below is the sample video to show what we are going to build. Note that we are going to implement this project using the Kotlin language. 
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 view binding dependency
Go to build.gradle(app) and the following dependency inside the android tag and click sync now.
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. It has only a single Recycler view which we will use to show our data.
XML
<?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"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:background="#F5F8FD"    android:layout_height="match_parent"    tools:context=".MainActivity">          <!--Add recycler view to main activity-->    <androidx.recyclerview.widget.RecyclerView        android:id="@+id/rv_list"        android:layout_width="match_parent"        android:layout_height="match_parent"        tools:listitem="@layout/single_item"        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />  </androidx.constraintlayout.widget.ConstraintLayout>
Step 4: Create a new layout file and name it a single_item.xml file
Go to the single_item.xml file and refer to the following code. Below is the code for the single_item.xml file. It is the single item layout that we will use in RecyclerView.
XML
<?xml version="1.0" encoding="utf-8"?><com.google.android.material.card.MaterialCardView     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_marginBottom="10dp"    android:layout_marginStart="5dp"    android:layout_marginEnd="5dp"    android:layout_height="110dp">      <androidx.constraintlayout.widget.ConstraintLayout        android:layout_width="match_parent"        android:layout_height="match_parent">                <!--Add image view, We will not set any data here.-->        <ImageView            android:id="@+id/iv_language"            android:layout_width="90dp"            android:layout_height="90dp"            android:layout_marginStart="20dp"            android:layout_marginTop="10dp"            android:scaleType="fitCenter"            android:src="@mipmap/ic_launcher"            app:layout_constraintLeft_toLeftOf="parent"            app:layout_constraintTop_toTopOf="parent" />                <!--Text view for showing the language name-->        <TextView            android:id="@+id/tv_lang_name"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_marginStart="30dp"            android:layout_marginTop="20dp"            android:text="Language"            android:textSize="20sp"            android:textColor="@color/black"            android:textStyle="bold"            app:layout_constraintLeft_toRightOf="@id/iv_language"            app:layout_constraintTop_toTopOf="parent" />                <!--Text view fr showing exp-->        <TextView            android:layout_width="wrap_content"            android:layout_height="wrap_content"            app:layout_constraintTop_toBottomOf="@id/tv_lang_name"            app:layout_constraintLeft_toLeftOf="@id/tv_lang_name"            android:text="1 Year exp"            android:id="@+id/tv_exp"            android:textSize="16sp"            android:layout_marginTop="15dp"/>                <!--Text view for showing the options menu-->        <TextView            android:id="@+id/textViewOptions"            android:layout_width="20dp"            android:gravity="center"            android:layout_height="30dp"            android:layout_alignParentTop="true"            android:textStyle="bold"            app:layout_constraintRight_toRightOf="parent"            app:layout_constraintTop_toTopOf="parent"            android:layout_margin="20dp"            android:text="⋮"            android:textAppearance="?android:textAppearanceLarge" />              </androidx.constraintlayout.widget.ConstraintLayout>  </com.google.android.material.card.MaterialCardView>
Step 5: Create a new model class
Create a new class Language.kt we will use data of custom generic “Language” to pass in the list that will be shown in recycler view.
Kotlin
// this is the Language model classclass Language(    val name : String ="",    val exp : String = "")
Step 6: Working with the adapter class
Create a new class RvAdapter.kt this will act as an Adapter class for the recycler view. Comments are added before the code for better understanding.
Kotlin
import android.view.LayoutInflaterimport android.view.ViewGroupimport androidx.recyclerview.widget.RecyclerViewimport com.geeksforgeeks.rvadapterviewbinding.databinding.SingleItemBinding  class RvAdapter(    private var languageList: List<Language>,    private var optionsMenuClickListener: OptionsMenuClickListener) : RecyclerView.Adapter<RvAdapter.ViewHolder>() {      // create an interface for onClickListener    // so that we can handle data most effectively in MainActivity.kt    interface OptionsMenuClickListener {        fun onOptionsMenuClicked(position: Int)    }      // create an inner class with name ViewHolder    // It takes a view argument, in which pass the generated class of single_item.xml    // ie SingleItemBinding and in the RecyclerView.ViewHolder(binding.root) pass it like this    inner class ViewHolder(val binding: SingleItemBinding) : RecyclerView.ViewHolder(binding.root)      // inside the onCreateViewHolder inflate the view of SingleItemBinding    // and return new ViewHolder object containing this layout    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {        val binding = SingleItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)        return ViewHolder(binding)    }      // bind the items with each item of the list languageList which than will be    // shown in recycler view    // to keep it simple we are not setting any image data to view    override fun onBindViewHolder(holder: ViewHolder, position: Int) {        with(holder){            with(languageList[position]){                // set text to language name                binding.tvLangName.text = this.name                // set exp                binding.tvExp.text = this.exp                // implement on clickListener and pass position of the item                // rest we will handle in MainActivity.kt                binding.textViewOptions.setOnClickListener {                    optionsMenuClickListener.onOptionsMenuClicked(position)                }            }        }    }      // return the size of languageList    override fun getItemCount(): Int {        return languageList.size    }}
Step 7: Working with MainActivity.kt
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 androidx.appcompat.app.AppCompatActivityimport android.os.Bundleimport android.view.MenuItemimport android.widget.PopupMenuimport android.widget.Toastimport androidx.core.view.getimport androidx.recyclerview.widget.LinearLayoutManagerimport com.geeksforgeeks.rvadapterviewbinding.databinding.ActivityMainBinding  class MainActivity : AppCompatActivity() {      // view binding for the activity    private var _binding: ActivityMainBinding? = null    private val binding get() = _binding!!      // get reference to the adapter class    private var languageList = ArrayList<Language>()    private lateinit var rvAdapter: RvAdapter      override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        _binding = ActivityMainBinding.inflate(layoutInflater)        setContentView(binding.root)          // define layout manager for the Recycler view        binding.rvList.layoutManager = LinearLayoutManager(this)        // attach adapter to the recycler view and also handle item click        rvAdapter = RvAdapter(languageList , object : RvAdapter.OptionsMenuClickListener{            // implement the required method            override fun onOptionsMenuClicked(position: Int) {                // this method will handle the onclick options click                // it is defined below                performOptionsMenuClick(position)            }        })        // add adapter to the recycler view        binding.rvList.adapter = rvAdapter          // create objects of Language        // create some row data        val language1 = Language("Java" , "3 Year exp" )        val language2 = Language("Kotlin" , "2 Year exp" )        val language3 = Language("Python" , "1 Year exp" )        val language4 = Language("CPP" , "5 Year exp" )        val language5 = Language("PHP" , "No exp" )          // pass raw data t rhe list        languageList.add(language1)        languageList.add(language2)        languageList.add(language3)        languageList.add(language4)        languageList.add(language5)          rvAdapter.notifyDataSetChanged()    }      // this method will handle the onclick options click    private fun performOptionsMenuClick(position: Int) {        // create object of PopupMenu and pass context and view where we want        // to show the popup menu        val popupMenu = PopupMenu(this , binding.rvList[position].findViewById(R.id.textViewOptions))        // add the menu        popupMenu.inflate(R.menu.options_menu)        // implement on menu item click Listener        popupMenu.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener{            override fun onMenuItemClick(item: MenuItem?): Boolean {                when(item?.itemId){                    R.id.delete -> {                        // here are the logic to delete an item from the list                        val tempLang = languageList[position]                        languageList.remove(tempLang)                        rvAdapter.notifyDataSetChanged()                        return true                    }                    // in the same way you can implement others                    R.id.item2 -> {                        // define                        Toast.makeText(this@MainActivity , "Item 2 clicked" , Toast.LENGTH_SHORT).show()                        return true                    }                    R.id.item3 -> {                        // define                        Toast.makeText(this@MainActivity , "Item 3 clicked" , Toast.LENGTH_SHORT).show()                        return true                    }                }                return false            }        })        popupMenu.show()    }      // on destroy of view make the binding reference to null    override fun onDestroy() {        super.onDestroy()        _binding = null    }}
Output:
Github repo here. 
Kotlin Android
Android
Kotlin
Android
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Android SDK and it's Components
Flutter - Custom Bottom Navigation Bar
How to Add Views Dynamically and Store Data in Arraylist in Android?
Retrofit with Kotlin Coroutine in Android
How to Post Data to API using Retrofit in Android?
Android UI Layouts
Kotlin Array
How to Add Views Dynamically and Store Data in Arraylist in Android?
Retrofit with Kotlin Coroutine in Android