There are 2 ways to do this
Add SearchView by Menu
Add android.widget.SearchView
to menu xml (e.g. menu_main.xml
).
<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.luasoftware.luapass.MainActivity">
<item android:id="@+id/action_search"
android:title="Search"
android:icon="@drawable/ic_search_white_24dp"
app:showAsAction="collapseActionView|always"
app:actionViewClass="androidx.appcompat.widget.SearchView" />
<item
android:id="@+id/action_settings"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>
2019-04-13: Use app:actionViewClass="androidx.appcompat.widget.SearchView"
instead of app:actionViewClass="android.widget.SearchView"
. android.widget.SearchView has outdated UI and some UI bugs.
Activity code to access SearchView.
By default, a search icon is shown, where it shall expand into search field on click.
If you want the search field to always be visible, then call setIconifiedByDefault(false).
import androidx.appcompat.widget.SearchViewclass MainActivity : AppCompatActivity() { override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) val searchItem = menu.findItem(R.id.action_search) // Optional: if you want to expand SearchView from icon to edittext view searchItem.expandActionView() val searchView = searchItem.actionView as SearchView }}
Add SearchView in AppBarLayout/Toolbar
- Add
SearchView
withinToolbar
- Add focusable
LinearLayout
to prevent Keyboard from popup on activity load - Set toolbar
contentInsetLeft/Start
andcontentInsetLeft/Start
to0dp
to reduce left padding of SearchView
<android.support.design.widget.CoordinatorLayout ..>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:contentInsetLeft="0dp"
android:contentInsetStart="0dp"
app:contentInsetLeft="0dp"
app:contentInsetStart="0dp"
app:popupTheme="@style/AppTheme.PopupOverlay">
<!-- dummy to catch focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<android.support.v7.widget.SearchView
android:id="@+id/search"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:nextFocusUp="@id/search"
android:nextFocusLeft="@id/search"
/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
// expand searchView as EditText (default is a search icon)search.setIconifiedByDefault(false)search.queryHint = "Search"
Delay trigger for search query text changes
The sample below listen for search query as it is typed, delaying the trigger event from 300ms to 1s depending on the length of the string.
search.setOnQueryTextListener(object: SearchView.OnQueryTextListener { var timer = Timer() override fun onQueryTextSubmit(query: String?): Boolean { return false } override fun onQueryTextChange(newText: String): Boolean { timer.cancel() val sleep = when(newText.length) { 1 -> 1000L 2,3 -> 700L 4,5 -> 500L else -> 300L } timer = Timer() timer.schedule(sleep) { if (!newText.isNullOrEmpty()) { // search } } return true } })
NOTE: import kotlin.concurrent.schedule
is required for timer.schedule
.
References: