Kotlin Listview Searchview Android Tutorial Example

kotlin splash screen, kotlin listview searchview, kotlin app intro slider, kotlin webview with progress bar, kotlin webview back forward navigation, kotlin parse json from url, kotlin login register android, kotlin upload image from gallery, kotlin upload image from camera, kotlin sqlite database, kotlin sqlite crud

Welcome to kotlin listview searchview tutorial example.

In this article, you will learn how to implement search filter functionality for listview using the searchview.

Search filter is very basic functionality and you will need this in almost every case where members of listview is very high.

Java Code

If you are looking for the same tutorial in JAVA language then read : Android SearchView ListView in JAVA

First of all, see the below output result of this example.

 

Step 1. New Project For Kotlin

In this step ,you need to make a new project in android studio. Here, you need to add kotlin support or select project language as a kotlin.

Along with adding kotlin support, you also need to select empty activity as a default activity.

Step 2. Separate Row file for Listview

Let us make a new layout file that will create a specific view for each listview item.

Inside, res->layout directory, add a new XML layout file and give it a name like lv_item.xml

You should add the following source snippet in lv_item.xml file.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="10dp">


    <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

</RelativeLayout>

Step 3. Making Model File

Now create a new Kotlin file or class and give it a name like MovieNames.kt

Below is the source code lines for MovieNames.kt file.

class MovieNames{

    private val movieName: String

    constructor(movieName: String){
        //code
        this.movieName = movieName
    }

    fun getAnimalName(): String {
        return this.movieName
    }

}

This MovieNames.kt file is working as a model class for listview.

We will create an object of this class for each listview row item. We will do this in the Main Activity.kt class.

See the source code of this class. It contains one constructor. There is one string variable in this constructor.

Above the constructor, we have defined one simple string variable. We will assign the value of the constructor string variable to the simple string variable.

Then there is a method called getAnimalName() 

This getAnimalName() method will return the value of the simple string variable.

Step 4. Writing the Adapter Class

Make a new kotlin class and set it’s name as ListViewAdapter.kt

In this ListViewAdapter.kt class, write down the following source code lines

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.TextView

import java.util.ArrayList
import java.util.Locale

class ListViewAdapter(
    // Declare Variables

    internal var mContext: Context
) : BaseAdapter() {
    internal var inflater: LayoutInflater
    private val arraylist: ArrayList<MovieNames>

    init {
        inflater = LayoutInflater.from(mContext)
        this.arraylist = ArrayList()
        this.arraylist.addAll(MainActivity.movieNamesArrayList)
    }

    inner class ViewHolder {
        internal var name: TextView? = null
    }

    override fun getCount(): Int {
        return MainActivity.movieNamesArrayList.size
    }

    override fun getItem(position: Int): MovieNames {
        return MainActivity.movieNamesArrayList[position]
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    override fun getView(position: Int, view: View?, parent: ViewGroup): View {
        var view = view
        val holder: ViewHolder
        if (view == null) {
            holder = ViewHolder()
            view = inflater.inflate(R.layout.lv_item, null)
            // Locate the TextViews in listview_item.xml
            holder.name = view!!.findViewById(R.id.name) as TextView
            view.tag = holder
        } else {
            holder = view.tag as ViewHolder
        }
        // Set the results into TextViews
        holder.name!!.setText(MainActivity.movieNamesArrayList[position].getAnimalName())
        return view
    }

    // Filter Class
    fun filter(charText: String) {
        var charText = charText
        charText = charText.toLowerCase(Locale.getDefault())
        MainActivity.movieNamesArrayList.clear()
        if (charText.length == 0) {
            MainActivity.movieNamesArrayList.addAll(arraylist)
        } else {
            for (wp in arraylist) {
                if (wp.getAnimalName().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.movieNamesArrayList.add(wp)
                }
            }
        }
        notifyDataSetChanged()
    }

}

An adapter class will bind the data source with the listview. Here, our data source will be the arraylist with the objects of MovieNames.kt class. We are getting this data source from below line

 this.arraylist.addAll(MainActivity.movieNamesArrayList)

Main Activity contains the movieNamesArrayList as a public access specifier. So we can use it in this adapter class.

See the following source lines

  override fun getView(position: Int, view: View?, parent: ViewGroup): View {
        var view = view
        val holder: ViewHolder
        if (view == null) {
            holder = ViewHolder()
            view = inflater.inflate(R.layout.lv_item, null)
            // Locate the TextViews in listview_item.xml
            holder.name = view!!.findViewById(R.id.name) as TextView
            view.tag = holder
        } else {
            holder = view.tag as ViewHolder
        }
        // Set the results into TextViews
        holder.name!!.setText(MainActivity.movieNamesArrayList[position].getAnimalName())
        return view
    }

This method will create the view for each child row of listview.

It will inflate the lv_item.xml file as the base of creating look and feel of row item.

lv_item.xml file contains one text view. Compiler will use movieNamesArrayList o set the name of the movie in this text view.

Now see the following lines

 // Filter Class
    fun filter(charText: String) {
        var charText = charText
        charText = charText.toLowerCase(Locale.getDefault())
        MainActivity.movieNamesArrayList.clear()
        if (charText.length == 0) {
            MainActivity.movieNamesArrayList.addAll(arraylist)
        } else {
            for (wp in arraylist) {
                if (wp.getAnimalName().toLowerCase(Locale.getDefault()).contains(charText)) {
                    MainActivity.movieNamesArrayList.add(wp)
                }
            }
        }
        notifyDataSetChanged()
    }

A filter() function is the heart of this search view listview kotlin tutorial.

This function will get the search query via it’s parameter. Then it will save this query in one separate variable.

Then clear the movieNamesArrayList . Now it will check how many words are there in search query. If zero then it will again fill all the movie names in movieNamesArrayList

But if not zero then it will create one for loop. In every iteration of for loop, compiler will get the movie name and will check if it contains the words of search query. If yes then it will simply add this movie name in movieNamesArrayList otherwise not.

Step 5. Main Activity Writings

You should have two files for main activity : activity_main.xml and MainActivity.kt

In your activity_main.xml file, add the following code snippet

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent">

    <SearchView
            android:id="@+id/search"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:iconifiedByDefault="false">

        <requestFocus />
    </SearchView>

    <ListView
            android:id="@+id/listview"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@+id/search" />

</RelativeLayout>

One search view and one listview is there in this XML file. Search is above the listview.

Now in MainActivity.kt file, write down the below source lines

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.AdapterView
import android.widget.ListView
import android.widget.SearchView
import android.widget.Toast

import java.util.ArrayList

class MainActivity : AppCompatActivity(), SearchView.OnQueryTextListener {

    // Declare Variables
    private var list: ListView? = null
    private var adapter: ListViewAdapter? = null
    private var editsearch: SearchView? = null
    private var moviewList: Array<String>? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Generate sample data

        moviewList = arrayOf(
            "Xmen",
            "Titanic",
            "Captain America",
            "Iron man",
            "Rocky",
            "Transporter",
            "Lord of the rings",
            "The jungle book",
            "Tarzan",
            "Cars",
            "Shreck"
        )

        // Locate the ListView in listview_main.xml
        list = findViewById(R.id.listview) as ListView

        movieNamesArrayList = ArrayList()

        for (i in moviewList!!.indices) {
            val movieNames = MovieNames(moviewList!![i])
            // Binds all strings into an array
            movieNamesArrayList.add(movieNames)
        }

        // Pass results to ListViewAdapter Class
        adapter = ListViewAdapter(this)

        // Binds the Adapter to the ListView
        list!!.adapter = adapter

        // Locate the EditText in listview_main.xml
        editsearch = findViewById(R.id.search) as SearchView
        editsearch!!.setOnQueryTextListener(this)

        list!!.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            Toast.makeText(
                this@MainActivity,
                movieNamesArrayList[position].getAnimalName(),
                Toast.LENGTH_SHORT
            ).show()
        }
    }

    override fun onQueryTextSubmit(query: String): Boolean {

        return false
    }

    override fun onQueryTextChange(newText: String): Boolean {
        adapter!!.filter(newText)
        return false
    }

    companion object {
        var movieNamesArrayList = ArrayList<MovieNames>()
    }
}

Understand Main Ativity

Let us read each line from above snippet.

First of all, see the below code

  // Declare Variables
    private var list: ListView? = null
    private var adapter: ListViewAdapter? = null
    private var editsearch: SearchView? = null
    private var moviewList: Array<String>? = null

Above snippet is declaring four variables. First one is listview object, second one is adapter object, third is searchview object and last one is String arraylist.

Now see the following lines

  moviewList = arrayOf(
            "Xmen",
            "Titanic",
            "Captain America",
            "Iron man",
            "Rocky",
            "Transporter",
            "Lord of the rings",
            "The jungle book",
            "Tarzan",
            "Cars",
            "Shreck"
        )

We are just filling the string array variable with the names of the movies. This will be the primary data source.

Now look at the following code lines

 movieNamesArrayList = ArrayList()

        for (i in moviewList!!.indices) {
            val movieNames = MovieNames(moviewList!![i])
            // Binds all strings into an array
            movieNamesArrayList.add(movieNames)
        }

movieNamesArrayList is the arraylist with the objects of the MovieNames classes.

First line is initializing the variable. Then there is one for loop.

Every iteration of for loop will make a new object of MovieNames class. In the parameter, we will add the movie name from string array variable moviewList

After creating an object, we will add this object into movieNamesArrayList . Thus one iteration of for loop is complete.

Number of for loop iterations are equal to the number of members in the string array variable moviewList

Now focus on the below code

   // Pass results to ListViewAdapter Class
        adapter = ListViewAdapter(this)

        // Binds the Adapter to the ListView
        list!!.adapter = adapter

First line is initializing the adapter object.

Second one is simply binding the adapter to the listview.

Now read the below code

 editsearch = findViewById(R.id.search) as SearchView
        editsearch!!.setOnQueryTextListener(this)

First one is finding the searchview from id and second one is defining a query listener.

When you define the search query listener, you need to override two functions and they are as the following

 override fun onQueryTextSubmit(query: String): Boolean {

        return false
    }

    override fun onQueryTextChange(newText: String): Boolean {
        adapter!!.filter(newText)
        return false
    }

When the user types the search query, compiler will run the second function onQueryTextChanged() and it will execute the filter() function which is written in the ListViewAdapter.kt class.

filter() function will send the search query as it’s parameter.

Now see the below

   list!!.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
            Toast.makeText(
                this@MainActivity,
                movieNamesArrayList[position].getAnimalName(),
                Toast.LENGTH_SHORT
            ).show()
        }

Compiler will run the above code when the user clicks the listview. It will pop up one toast and will write the name of the movie in the toast.

Download Source For This Example

https://github.com/demonuts/kotlin-listview-searchview-android-tutorial-example