Добавить предложения пользовательского поиска

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

В диалоговом окне поиска Android или виджете поиска можно отображать подсказки для поиска на основе последних поисковых запросов. Например, если пользователь вводит запрос "щенки", этот запрос отобразится в качестве подсказки при повторном вводе. На рисунке 1 показан пример диалогового окна поиска с подсказками для последних запросов.

Прежде чем начать, реализуйте в своем приложении диалоговое окно поиска или виджет поиска для выполнения базовых запросов. Инструкции по созданию интерфейса поиска см. в разделе «Создание интерфейса поиска» .

Основы

Рисунок 1. Скриншот диалогового окна поиска с последними предложениями по запросам.

Последние подсказки — это сохраненные поисковые запросы. Когда пользователь выбирает подсказку, ваше поисковое действие получает интент ACTION_SEARCH содержащий подсказку в качестве поискового запроса, который ваше поисковое действие уже обрабатывает.

Чтобы предложить варианты решения актуальных вопросов, вам необходимо:

  • Реализуйте функцию поиска.
  • Создайте поставщика контента, который наследует SearchRecentSuggestionsProvider , и объявите его в манифесте вашего приложения.
  • Измените конфигурацию поиска, указав информацию о поставщике контента, предоставляющем поисковые подсказки.
  • Сохраняйте запросы в своем поставщике контента каждый раз, когда выполняется поиск.

Подобно тому, как система Android отображает диалоговое окно поиска, она также отображает подсказки поиска под этим диалоговым окном или виджетом поиска. Вы указываете источник, из которого система получает подсказки.

Когда система определяет, что ваша активность доступна для поиска, и предоставляет поисковые подсказки, при вводе пользователем запроса происходит следующее:

  1. Система принимает текст поискового запроса — всё, что пользователь начинает вводить, — и отправляет запрос поставщику контента, содержащий ваши предложения.
  2. Ваш поставщик контента возвращает Cursor , указывающий на все подсказки, соответствующие тексту поискового запроса.
  3. Система отображает список подсказок, предоставленных Cursor .

После отображения последних подсказок по запросам может произойти следующее:

  • Если пользователь вводит другую клавишу или каким-либо образом изменяет запрос, описанные выше шаги повторяются, и список подсказок обновляется.
  • Если пользователь выполняет поиск, предложенные варианты игнорируются, и поиск передается в ваше поисковое окно с помощью обычного интента ACTION_SEARCH .
  • Если пользователь выбирает предложенный вариант, в вашу поисковую активность отправляется интент ACTION_SEARCH , использующий предложенный текст в качестве запроса.

Класс SearchRecentSuggestionsProvider , который вы расширяете для своего поставщика контента, автоматически выполняет работу на предыдущих шагах, поэтому писать нужно совсем немного кода.

Создайте поставщика контента.

Для предоставления подсказок по последним запросам вам потребуется реализация класса SearchRecentSuggestionsProvider . Этот класс делает все за вас. Вам нужно лишь написать конструктор класса, который выполняет всего одну строку кода.

Например, вот полная реализация поставщика контента для подсказок по последним запросам:

Котлин

class MySuggestionProvider : SearchRecentSuggestionsProvider() {
    init {
        setupSuggestions(AUTHORITY, MODE)
    }

    companion object {
        const val AUTHORITY = "com.example.MySuggestionProvider"
        const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
    }
}

Java

public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
    public final static String AUTHORITY = "com.example.MySuggestionProvider";
    public final static int MODE = DATABASE_MODE_QUERIES;

    public MySuggestionProvider() {
        setupSuggestions(AUTHORITY, MODE);
    }
}

При вызове функции setupSuggestions() передаются имя поискового органа и режим базы данных. Поисковый орган может представлять собой любую уникальную строку, но рекомендуется использовать полное имя поставщика контента, например, имя пакета, за которым следует имя класса поставщика. Например, "com.example.MySuggestionProvider" .

Режим работы базы данных должен включать DATABASE_MODE_QUERIES и может дополнительно включать параметр DATABASE_MODE_2LINES , который добавляет столбец в таблицу подсказок, позволяя добавлять вторую строку текста к каждой подсказке. Если вы хотите добавить две строки в каждую подсказку, см. следующий пример:

Котлин

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Объявите поставщика контента в манифесте вашего приложения, используя ту же строку полномочий, что и в классе SearchRecentSuggestionsProvider и в конфигурации поиска. Например:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="com.example.MySuggestionProvider" />
    ...
</application>

Измените конфигурацию поиска.

Чтобы настроить систему на использование вашего поставщика подсказок, добавьте атрибуты android:searchSuggestAuthority и android:searchSuggestSelection к элементу <searchable> в файле конфигурации поиска. Например:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

Значение параметра android:searchSuggestAuthority должно представлять собой полное имя вашего поставщика контента, точно соответствующее полномочиям, используемым в поставщике контента, например, "com.example.MySuggestionProvider" в приведенных выше примерах.

Значение параметра android:searchSuggestSelection должно представлять собой один вопросительный знак, перед которым стоит пробел: " ?" . Это заполнитель для аргумента выбора SQLite, и он автоматически заменяется текстом запроса, введенным пользователем.

Сохранение запросов

Чтобы заполнить коллекцию последних запросов, добавьте каждый запрос, полученный вашей активностью с возможностью поиска, в ваш SearchRecentSuggestionsProvider . Для этого создайте экземпляр SearchRecentSuggestions и вызывайте saveRecentQuery() каждый раз, когда ваша активность с возможностью поиска получает запрос. Например, вот как можно сохранить запрос в методе onCreate() вашей активности:

Котлин

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
                    .saveRecentQuery(query, null)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent  = getIntent();

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
        suggestions.saveRecentQuery(query, null);
    }
}

Конструктор SearchRecentSuggestionsProvider требует наличия тех же полномочий и режима работы базы данных, которые указаны в вашем поставщике контента.

Метод saveRecentQuery() принимает строку поискового запроса в качестве первого параметра и, при необходимости, вторую строку для включения во вторую строку подсказки или значение null. Второй параметр используется только в том случае, если вы включили двухстрочный режим для подсказок поиска с помощью DATABASE_MODE_2LINES . Если вы включили двухстрочный режим, то текст запроса будет сопоставляться со второй строкой, когда система будет искать соответствующие подсказки.

Очистить данные подсказок

Для защиты конфиденциальности пользователя всегда предоставляйте ему возможность очистить историю последних запросов. Чтобы очистить историю запросов, вызовите метод clearHistory() . Например:

Котлин

SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
        .clearHistory()

Java

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
        HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();

Выполните эту операцию, выбрав соответствующий пункт меню, пункт настроек или кнопку «Очистить историю поиска». Предоставьте диалоговое окно подтверждения, чтобы убедиться, что пользователь действительно хочет удалить свою историю поиска.