Настройте интерфейс поиска

Мы рекомендуем использовать виджет SearchView в качестве элемента на панели приложения, чтобы обеспечить функции поиска в вашем приложении. Как и в случае со всеми элементами на панели приложения, вы можете определить, чтобы SearchView отображался всегда или только тогда, когда есть место. Вы также можете определить его как свертываемое действие, которое сначала отображает SearchView в виде значка, а затем занимает всю панель приложения в качестве поля поиска, когда пользователь касается значка.

Добавьте SearchView на панель приложения.

Чтобы добавить виджет SearchView на панель приложения, создайте в своем проекте файл с именем res/menu/options_menu.xml и добавьте в него следующий код. Этот код определяет, как создать элемент поиска, например, используемый значок и заголовок элемента. Атрибут collapseActionView позволяет вашему SearchView развернуться, чтобы занять всю панель приложения, и свернуть обратно в обычный элемент панели приложения, когда он не используется. Из-за ограниченного пространства панели приложений на мобильных устройствах мы рекомендуем использовать атрибут collapsibleActionView чтобы обеспечить лучшее взаимодействие с пользователем.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
        android:title="@string/search_title"
        android:icon="@drawable/ic_search"
        android:showAsAction="collapseActionView|ifRoom"
        android:actionViewClass="androidx.appcompat.widget.SearchView" />
</menu>

Если вам нужен более доступный значок поиска, создайте файл ic_search.xml в папке /res/drawable и включите в него следующий код:

<vector
    android:height="24dp"
    android:tint="#000000"
    android:viewportHeight="24"
    android:viewportWidth="24"
    android:width="24dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
        <path android:fillColor="@android:color/white" android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z"/>
</vector>

Чтобы отобразить SearchView на панели приложения, добавьте XML-ресурс меню res/menu/options_menu.xml в методе onCreateOptionsMenu() вашей активности:

Котлин

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    return true
}

Запуск приложения генерирует что-то вроде этого:

Изображение пустого экрана со значком поиска в верхней панели приложения.
Рисунок 1. Значок поиска в верхней панели приложения.

SearchView отображается на панели приложения вашего приложения, но не работает. Если вы нажмете на значок поиска, вы получите что-то вроде этого:

Изображение, показывающее режим поиска в действии.
Рисунок 2. SearchView в действии.

Чтобы сделать SearchView функциональным, необходимо определить, как будет вести себя SearchView .

Создайте конфигурацию поиска

Конфигурация поиска определяет поведение SearchView и определяется в файле res/xml/searchable.xml . Конфигурация поиска должна содержать как минимум атрибут android:label , имеющий то же значение, что и атрибут android:label элемента <application> или <activity> в манифесте Android. Однако мы также рекомендуем добавить атрибут android:hint чтобы дать пользователю представление о том, что вводить в поле поиска.

<?xml version="1.0" encoding="utf-8"?>

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_name"
        android:hint="@string/search_hint" />

В файле манифеста вашего приложения объявите элемент <meta-data> , который указывает на файл res/xml/searchable.xml . Объявите элемент в <activity> , в котором вы хотите отобразить SearchView .

<activity
android:name=".SearchResultsActivity"
android:exported="false"
android:label="@string/title_activity_search_results"
android:launchMode="singleTop"
android:theme="@style/Theme.AppCompat.Light">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
        android:name="android.app.searchable"
        android:resource="@xml/searchable" />
</activity>

В созданном методе onCreateOptionsMenu() свяжите конфигурацию поиска с SearchView , вызвав setSearchableInfo(SearchableInfo) :

Котлин

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.options_menu, menu)

    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    val searchView = menu.findItem(R.id.search).actionView as SearchView
    val component = ComponentName(this, SearchResultsActivity::class.java)
    val searchableInfo = searchManager.getSearchableInfo(component)
    searchView.setSearchableInfo(searchableInfo)
    return true
}

Вызов getSearchableInfo() получает объект SearchableInfo , созданный из XML-файла конфигурации поиска. Когда конфигурация поиска правильно связана с вашим SearchView и пользователь отправляет запрос, SearchView запускает действие с намерением ACTION_SEARCH . Затем вам понадобится действие, которое может фильтровать это намерение и обрабатывать поисковый запрос.

Создайте действие с возможностью поиска

Действие с возможностью поиска фильтрует намерение ACTION_SEARCH и ищет запрос в наборе данных. Чтобы создать действие с возможностью поиска, объявите действие по вашему выбору для фильтрации по намерению ACTION_SEARCH :

<activity android:name=".SearchResultsActivity" ... >
    ...
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    ...
</activity>

В своей активности поиска обрабатывайте намерение ACTION_SEARCH , проверяя его в методе onCreate() .

Котлин

class SearchResultsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_search_results)
        handleIntent(intent)
    }

    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            val query = intent.getStringExtra(SearchManager.QUERY)
            Log.d("SEARCH", "Search query was: $query")
        }
    }
}

Теперь SearchView может принять запрос пользователя и начать поисковую деятельность с намерением ACTION_SEARCH .

После получения поискового запроса вы можете передать его в ViewModel , где вы сможете использовать его на других уровнях вашей архитектуры для получения результатов поиска для отображения.