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
- add component to the app as menu item or directly in layout resource
- provide a set of suggestions and handle its selection by the user
- handling input text
SearchView menu item
<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.
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.
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.
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.
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.