SearchView

A SearchView provides a user interface to enter a search query and submit a request to a search provider. Shows a list of query suggestions or results, if available, and allows the user to pick a suggestion or result to launch into.

Main tasks related with SearchView are

  1. add component to the app as menu item or directly in layout resource
  2. provide a set of suggestions and handle its selection by the user
  3. handling input text

SearchView menu item

Menu item for SearchView
<menu 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"
    tools:context="com.example.MyActivity">

    <item
        android:id="@+id/action_search"
        android:icon="@android:drawable/ic_menu_search"
        app:showAsAction="always|collapseActionView"
        app:actionViewClass="androidx.appcompat.widget.SearchView"
        android:title="@string/menu_action_search"/>

    ...
</menu>

You can customize the SearchView from the options menu creation method.

onCreateOptionsMenu example
private var searchView: SearchView? = null
// ...

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the menu; this adds items 
    // to the toolbar if it is present.
    menuInflater.inflate(R.menu.web_activity_menu, menu)

    val searchItem = menu.findItem(R.id.action_search)
    searchView = searchItem.actionView as SearchView
    setupSearchView(searchView!!)

    // ...   
    return true
}

provide suggestions

SearchView accept CursorAdapter object to get suggestions.

Create adapter full example
searchView.suggestionsAdapter = searchSuggestionsAdapter

SimpleCursorAdapter and MatrixCursor classes are used for simplify example. In real app you can use a content provider to get cursor or implement own CursorAdapter. Also you can replace android.R.id.text1 by own layout.

selection of suggestion

The OnSuggestionListener interface allows you to handle selection of suggestion by the user. Return true from methods if you don't want default handling of events.

Handle suggestions
val suggestionListener = object : SearchView.OnSuggestionListener {
    override fun onSuggestionSelect(position: Int): Boolean {
        return false
    }

    override fun onSuggestionClick(position: Int): Boolean {
        if (cursorSuggestions.moveToPosition(position)) {
            val query: String = cursorSuggestions.getString(
                     cursorSuggestions.getColumnIndex("NAME"))
            searchView.setQuery(query, true)
        }
        
        return true
        }
}

searchView.setOnSuggestionListener(suggestionListener)

handling input text

The OnQueryTextListener interface provides callbacks for changes to the query text. For example, to filter suggestions.

Return true from methods if you don't want default handling of events.

Code example
 val queryListener: SearchView.OnQueryTextListener = 
                 object : SearchView.OnQueryTextListener {
    
    override fun onQueryTextSubmit(query: String?): Boolean {
        query?.also {
                    // do something with query
            Toast.makeText(thisMyActivity,"User inputs query $query",
                        Toast.LENGTH_LONG).show()
        }
        
        return true
    }

    override fun onQueryTextChange(newText: String?): Boolean {
         // create new cursor with suggestions 
        var _id = 0
        cursorSuggestions = MatrixCursor(columnsSuggestions)

        newText?.also { lNewText ->
            searchSuggestions.forEach {
                if (it.startsWith(lNewText.trim().toLowerCase())) {
                    cursorSuggestions.addRow(arrayOf<Any>(_id, it))
                    ++_id
                }
            }
        }

        // apply new cursor
        searchView.suggestionsAdapter.apply {
            changeCursor(cursorSuggestions)
            notifyDataSetChanged()
        }
        return true
     }
}

searchView.setOnQueryTextListener(queryListener)

In real app you can use MVVM pattern and place code of onQueryTextChange() method into it.