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

Попробуйте способ создания композиций.
Jetpack Compose — рекомендуемый набор инструментов для создания пользовательского интерфейса для Android. Узнайте, как добавить функцию поиска в Compose.

Мы рекомендуем использовать виджет 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>

В вашем 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 , где он будет использоваться на других уровнях вашей архитектуры для получения результатов поиска и их отображения.