Android – SearchView con RecyclerView usando Kotlin

Muchas aplicaciones muestran grandes cantidades de datos en forma de lista y el usuario no puede revisar cada elemento de la lista para obtener el elemento que desea. Para filtrar estas listas dentro de la aplicación de Android, podemos usar SearchView para filtrarlas. En este artículo, crearemos una aplicación simple en la que implementaremos una vista de búsqueda en la vista de Android Recycler usando Kotlin.

Nota : si está buscando implementar Search View en Android con Recycler View usando Java. Vista de búsqueda en Android con Recycler View usando Java

Implementación paso a paso

Paso 1: crea un nuevo proyecto en Android Studio

Cómo crear/iniciar un nuevo proyecto en Android Studio

Paso 2: trabajar con el archivo activity_main.xml

Vaya a la aplicación > res > diseño > actividad_principal.xml y agregue el siguiente código a ese archivo. A continuación se muestra el código para el archivo activity_main.xml. 

XML

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    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:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
  
    <!--on below line we are creating a
         text for heading of our app-->
    <TextView
        android:id="@+id/idTVHeading"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:gravity="center"
        android:padding="4dp"
        android:text="@string/app_name"
        android:textAlignment="center"
        android:textColor="@color/purple_200"
        android:textSize="18sp"
        android:textStyle="bold" />
  
    <!--on below line we are creating a recycler view-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/idRVCourses"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/idTVHeading"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
  
</RelativeLayout>

Paso 3: Crear una clase modal para almacenar nuestros datos

Navegue a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él > Nuevo > clase Kotlin y nombre su clase como CourseRVModal y agréguele el siguiente código. Se agregan comentarios en el código para conocer en detalle. 

Kotlin

package com.gtappdevelopers.kotlingfgproject
  
data class CourseRVModal(
    // on below line we are creating a two variable
    // one for course name and other for course image.
    var courseName: String,
    var courseImg: Int
)

Paso 4: crear un archivo de diseño para nuestro elemento de RecyclerView

Vaya a la aplicación > res > diseño > haga clic con el botón derecho en él > Nuevo > archivo de recursos de diseño y nombre su diseño como curso_rv_elemento y agréguele el siguiente código. 

XML

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="5dp"
    app:cardCornerRadius="5dp"
    app:cardElevation="4dp">
    
    <!--on below line we are creating 
        a linear layout for grid view item-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
  
        <!--on below line we are creating
             a simple image view-->
        <ImageView
            android:id="@+id/idIVCourse"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_gravity="center"
            android:layout_margin="8dp"
            android:padding="5dp"
            android:src="@mipmap/ic_launcher" />
  
        <!--on below line we are creating
             a simple text view-->
        <TextView
            android:id="@+id/idTVCourse"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:layout_margin="5dp"
            android:padding="4dp"
            android:text="@string/app_name"
            android:textAlignment="textStart"
            android:textColor="@color/black"
            android:textStyle="bold"
            tools:ignore="RtlCompat" />
  
    </LinearLayout>
  
</androidx.cardview.widget.CardView>

Paso 5: crear una clase de adaptador para configurar datos en elementos de nuestro RecyclerView

Navegue a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él > Nuevo > clase Kotlin y asígnele el nombre CourseRVAdapter y agréguele el siguiente código. 

Kotlin

package com.gtappdevelopers.kotlingfgproject
  
import android.content.Context
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
  
// on below line we are creating a course rv adapter class.
class CourseRVAdapter(
    // on below line we are passing variables as course list and context
    private var courseList: ArrayList<CourseRVModal>,
) : RecyclerView.Adapter<CourseRVAdapter.CourseViewHolder>() {
    override fun onCreateViewHolder(
        parent: ViewGroup,
        viewType: Int
    ): CourseRVAdapter.CourseViewHolder {
        // this method is use to inflate the layout file
        // which we have created for our recycler view.
        // on below line we are inflating our layout file.
        val itemView = LayoutInflater.from(parent.context).inflate(
            R.layout.course_rv_item,
            parent, false
        )
          
        // at last we are returning our view holder 
        // class with our item View File.
        return CourseViewHolder(itemView)
    }
  
    // method for filtering our recyclerview items.
    fun filterList(filterllist: ArrayList<CourseRVModal>) {
        // below line is to add our filtered
        // list in our course array list.
        courseList = filterllist
        // below line is to notify our adapter
        // as change in recycler view data.
        notifyDataSetChanged()
    }
  
    override fun onBindViewHolder(holder: CourseRVAdapter.CourseViewHolder, position: Int) {
        // on below line we are setting data to our text view and our image view.
        holder.courseNameTV.text = courseList.get(position).courseName
        holder.courseIV.setImageResource(courseList.get(position).courseImg)
    }
  
    override fun getItemCount(): Int {
        // on below line we are returning 
        // our size of our list
        return courseList.size
    }
  
    class CourseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        // on below line we are initializing our course name text view and our image view.
        val courseNameTV: TextView = itemView.findViewById(R.id.idTVCourse)
        val courseIV: ImageView = itemView.findViewById(R.id.idIVCourse)
    }
}

Paso 6: Crear un archivo de menú para nuestro SearchView

Navegue a la aplicación> res> Haga clic con el botón derecho en él> Nuevo> Directorio y asigne un nombre a su directorio como menú. Después de crear un nuevo directorio, debemos crear un nuevo archivo de menú dentro de él. Para crear un nuevo archivo de menú. Navegue a la aplicación> res> menú> Haga clic con el botón derecho en él> Nuevo> archivo de recursos de menú, asígnele el nombre search_menu y agregue el código a continuación. 

XML

<?xml version="1.0" encoding="utf-8"?>
<menu 
    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:orientation="vertical">
  
    <!--item for our search view with its id-->
    <item
        android:id="@+id/actionSearch"
        android:icon="@android:drawable/ic_menu_search"
        android:title="Search"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        app:showAsAction="ifRoom|collapseActionView" />
  
</menu>

Paso 7: trabajar con el archivo MainActivity.kt

Vaya al archivo MainActivity.java 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

package com.gtappdevelopers.kotlingfgproject
  
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView
import androidx.recyclerview.widget.RecyclerView
  
class MainActivity : AppCompatActivity() {
  
    // on below line we are creating variables for 
    // our swipe to refresh layout, recycler view,
    // adapter and list.
    lateinit var courseRV: RecyclerView
    lateinit var courseRVAdapter: CourseRVAdapter
    lateinit var courseList: ArrayList<CourseRVModal>
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
         
        // on below line we are initializing our views ith their ids.
        courseRV = findViewById(R.id.idRVCourses)
  
        // on below line we are initializing our list
        courseList = ArrayList()
  
        // on below line we are initializing our adapter
        courseRVAdapter = CourseRVAdapter(courseList)
  
        // on below line we are setting adapter to our recycler view.
        courseRV.adapter = courseRVAdapter
  
        // on below line we are adding data to our list
        courseList.add(CourseRVModal("Android Development", R.drawable.android))
        courseList.add(CourseRVModal("C++ Development", R.drawable.c))
        courseList.add(CourseRVModal("Java Development", R.drawable.java))
        courseList.add(CourseRVModal("Python Development", R.drawable.python))
        courseList.add(CourseRVModal("JavaScript Development", R.drawable.js))
  
        // on below line we are notifying adapter
        // that data has been updated.
        courseRVAdapter.notifyDataSetChanged()
  
    }
  
    // calling on create option menu
    // layout to inflate our menu file.
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        // below line is to get our inflater
        val inflater = menuInflater
  
        // inside inflater we are inflating our menu file.
        inflater.inflate(R.menu.search_menu, menu)
  
        // below line is to get our menu item.
        val searchItem: MenuItem = menu.findItem(R.id.actionSearch)
  
        // getting search view of our item.
        val searchView: SearchView = searchItem.getActionView() as SearchView
  
        // below line is to call set on query text listener method.
        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener,
            android.widget.SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(p0: String?): Boolean {
                return false
            }
  
            override fun onQueryTextChange(msg: String): Boolean {
                // inside on query text change method we are
                // calling a method to filter our recycler view.
                filter(msg)
                return false
            }
        })
        return true
    }
  
    private fun filter(text: String) {
        // creating a new array list to filter our data.
        val filteredlist: ArrayList<CourseRVModal> = ArrayList()
  
        // running a for loop to compare elements.
        for (item in courseList) {
            // checking if the entered string matched with any item of our recycler view.
            if (item.courseName.toLowerCase().contains(text.toLowerCase())) {
                // if the item is matched we are
                // adding it to our filtered list.
                filteredlist.add(item)
            }
        }
        if (filteredlist.isEmpty()) {
            // if no item is added in filtered list we are
            // displaying a toast message as no data found.
            Toast.makeText(this, "No Data Found..", Toast.LENGTH_SHORT).show()
        } else {
            // at last we are passing that filtered
            // list to our adapter class.
            courseRVAdapter.filterList(filteredlist)
        }
    }
}

Ahora ejecute su aplicación para ver el resultado. 

Producción:

Publicación traducida automáticamente

Artículo escrito por chaitanyamunje y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *