Добавляем виджет поиска в App Bar (Android)

Добавлено: 18/03/2018 07:15 |  Обновлено: 18/06/2018 05:05 |  Добавил: nick |  Просмотры: 10898 Комментарии: 2
Вводная часть
В материале мы добавим поисковую строку в app bar (action bar). Кроме этого, реализуем возможность голосового поиска в строке и всплывающее меню последних поисковых запросов. Поиск как таковой мы осуществлять не будем, а просто будем выводить фразу из строки поиска в TextView главной активности.
Как это работает можно увидеть в моем приложении «Секретные карточки». Страница приложения в Google Play. ×
Встроенная строка поиска в app bar по умолчанию свернута и представлена в виде значка. При нажатии по значку появляется поле для ввода поисковой фразы. Давайте добавим этот виджет на панель приложения.

Создадим новый проект с шаблоном Empty Activity. Это самый простой шаблон с одной активностью, в котором даже нет знаменитой плавающей кнопки, которая, кстати, нам здесь и не понадобится.

После этого создадим xml-файл с названием searchable.xml. В данном файле можно указать будет ли в строке использоваться голосовой поиск, также можно задать свою подсказку для пользователя (search hint), и изменить другие параметры. Файл searchable.xml нужно разместить в папке xml. Данную папку вы должны создать сами в уже существующей папке ресурсов – res.

Содержимое файла searchable.xml должно быть следующим:
<?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"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
    android:searchSuggestAuthority="ru.phpnick.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>
В строке android:label="@string/app_name"атрибут android:label должен указывать на строковый ресурс с названием приложения.

В строке android:hint="@string/search_hint" задаем подсказку для пользователя. Пользователь видит данную подсказку перед тем как ввести поисковой запрос в поле поиска.

В строке android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" добавляем функцию голосового поиска.

В строке android:searchSuggestAuthority="ru.phpnick.MySuggestionProvider" мы указываем search authority для того чтобы включить показ последних поисковых запросов, во всплывающем окне под строкой поиска. Authority может быть любой уникальной строкой, но лучшей практикой считается указывать название пакета (в данном случае ru.phpnick) и название вашего класса, который расширяет класс SearchRecentSuggestionsProvider (в данном случае MySuggestionProvider).

В строке android:searchSuggestSelection=" ?" значение " ?" – это просто заполнитель для SQLite-функции select, в качестве аргумента которой будет использоваться значение из строки поиска.

С файлом searchable.xml закончили, далее нужно или создать новую Активность, которая будет осуществлять поиск и выводить его результат, или использовать для этих целей основную активность. Для простоты эксперимента мы будем использовать уже существующую MainActivity.

Но для начала мы должны указать, что мы будем использовать именно MainActivity, для этого откроем файл манифеста AndroidManifest.xml и добавим в него новые строки.

Внутри элемента <intent-filter> нужно добавить строчку:
<action android:name="android.intent.action.SEARCH" />
Сразу после элемента <intent-filter> (после закрывающего тега </intent-filter>) нужно добавить строчку:
<meta-data android:name="android.app.searchable"
    android:resource="@xml/searchable"/>
И сразу после элемента <activity> (после закрывающего тега </activity>) нужно добавить строчку:
<provider android:name=".MySuggestionProvider"
    android:authorities="ru.phpnick.MySuggestionProvider" />
Здесь мы указываем название своего класса, который расширяет класс SearchRecentSuggestionsProvider. Напоминаю, что данный класс требуется для того, чтобы включить показ последних поисковых запросов, во всплывающем окне под строкой поиска.

Создадим в папке с классом активности MainActivity.java новый файл MySuggestionProvider.java. Его содержимое должно быть следующим:
package ru.phpnick.englishwordbox;
import android.content.SearchRecentSuggestionsProvider;

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

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

}
Как видим кода здесь совсем немного. Метод setupSuggestions() передает значения констант AUTHORITY и MODE, которые будут использоваться далее.

Еще раз хочу напомнить, что в данном материале мы не будем ничего искать, а просто выведем фразу из строки поиска в TextView главной активности, для этого используем уже имеющийся виджет TextView, тот самый который выводит фразу «Hello World!» Изначально у него нет id, поэтому нам нужно его (id) добавить, чтобы обратиться к виджету из активности. Откроем файл activity_main.xml и внутри элемента добавим строчку:
android:id="@+id/textViewQuery"
Далее откроем файл MainActivity.java. В метод onCreate() добавим следующий код:
mQueryTextView = findViewById(R.id.textViewQuery);
Intent intent  = getIntent();

if (Intent.ACTION_SEARCH.equals(intent.getAction())) {

    String query = intent.getStringExtra(SearchManager.QUERY);
    mQueryTextView.setText(query);

    SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
            MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
    suggestions.saveRecentQuery(query, null);
}
В первой части кода мы получаем строку поиска из намерения ACTION_SEARCH и через метод setText() виджета TextView меняем выводимый им текст на строку поиска.

Во второй части кода, в методе saveRecentQuery() мы сохраняем новую поисковую фразу в коллекцию, содержащую все поисковые фразы, которые были введены нами в строку поиска.

После этого в метод onCreateOptionsMenu() нужно добавить код, активирующий виджет поиска (SearchView) и передающий в него настройки конфигурации.
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
// Здесь можно указать будет ли строка поиска изначально развернута или свернута в значок
searchView.setIconifiedByDefault(true);
Осталось в файл options_menu.xml добавить элемент поиска:
<item android:id="@+id/search"
    android:title="@string/search_title"
    android:icon="@drawable/ic_search"
    app:showAsAction="always"
    app:actionViewClass="android.support.v7.widget.SearchView" />
На этом все. Если теперь в строку поиска добавить какое-либо слово и нажать кнопку поиска на клавиатуре, данное слово заменит значение «Hello World!» виджета TextView. Не забывайте, что возможность голосового поиска и историю поисковых запросов мы также добавили.

Оставьте свой комментарий

Комментарии