XML que mejora la eficiencia de ListViews y GridViews En este artículo, explicaremos cómo usar el menú Opciones en cada elemento de RecyclerView. A continuación se muestra el video de muestra para mostrar lo que vamos a construir. Tenga en cuenta que vamos a implementar este proyecto utilizando el lenguaje Kotlin .
Implementación paso a paso
Paso 1: Crear un nuevo proyecto
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Kotlin como lenguaje de programación.
Paso 2: Agregar dependencia de enlace de vista
Vaya a build.gradle (aplicación) y la siguiente dependencia dentro de la etiqueta de Android y haga clic en sincronizar ahora .
construir características {
viewBinding true
}
Paso 3: trabajar con el archivo activity_main.xml
Vaya al archivo activity_main.xml y consulte el siguiente código. A continuación se muestra el código para el archivo activity_main.xml . Solo tiene una vista de Reciclador que usaremos para mostrar nuestros datos.
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>
Paso 4: Cree un nuevo archivo de diseño y asígnele el nombre de archivo single_item.xml
Vaya al archivo single_item.xml y consulte el siguiente código. A continuación se muestra el código para el archivo single_item.xml . Es el diseño de elemento único que usaremos en 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>
Paso 5: Crea una nueva clase modelo
Cree una nueva clase Language.kt, usaremos datos de » Idioma » genérico personalizado para pasar la lista que se mostrará en la vista de reciclado.
Kotlin
// this is the Language model class class Language( val name : String ="", val exp : String = "" )
Paso 6: trabajar con la clase de adaptador
Cree una nueva clase RvAdapter.kt que actuará como una clase de adaptador para la vista del reciclador. Los comentarios se agregan antes del código para una mejor comprensión.
Kotlin
import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import 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 } }
Paso 7: Trabajar con MainActivity.kt
Vaya al archivo MainActivity.kt y consulte el siguiente código. A continuación se muestra el código del archivo MainActivity.kt . Se agregan comentarios dentro del código para comprender el código con más detalle.
Kotlin
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.view.MenuItem import android.widget.PopupMenu import android.widget.Toast import androidx.core.view.get import androidx.recyclerview.widget.LinearLayoutManager import 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 } }
Producción:
Repositorio de Github aquí.