Tworzenie interfejsu wyszukiwania

Wypróbuj metodę Compose
Jetpack Compose to zalecany zestaw narzędzi interfejsu na Androida. Dowiedz się, jak dodać funkcję wyszukiwania w Compose.

Gdy zechcesz dodać do aplikacji funkcję wyszukiwania, Android pomoże Ci w implementacji interfejsu użytkownika za pomocą okna wyszukiwania, które pojawia się u góry okna aktywności, lub widżetu wyszukiwania, który możesz wstawić w układzie. Zarówno okno wyszukiwania, jak i widżet mogą przekazywać zapytanie użytkownika do konkretnego działania w aplikacji. Dzięki temu użytkownik może rozpocząć wyszukiwanie z dowolnego działania, w którym dostępne jest okno wyszukiwania lub widżet, a system uruchomi odpowiednie działanie, aby przeprowadzić wyszukiwanie i wyświetlić wyniki.

Inne funkcje dostępne w oknie wyszukiwania i widżecie:

  • Wyszukiwanie głosowe
  • Sugestie wyszukiwania na podstawie ostatnich zapytań
  • sugestie wyszukiwania, które pasują do rzeczywistych wyników w danych aplikacji.

Z tego dokumentu dowiesz się, jak skonfigurować aplikację, aby udostępniała interfejs wyszukiwania, który jest obsługiwany przez system Android w celu dostarczania zapytań za pomocą okna wyszukiwania lub widżetu wyszukiwania.

Przydatne materiały:

Podstawy

Zanim zaczniesz, zdecyduj, czy chcesz wdrożyć interfejs wyszukiwania za pomocą okna wyszukiwarki czy widżetu wyszukiwania. Oferują one te same funkcje wyszukiwania, ale w nieco inny sposób:

  • Okno wyszukiwania to komponent interfejsu kontrolowany przez system Android. Po aktywowaniu przez użytkownika okno wyszukiwania pojawi się u góry aktywności.

    Wszystkie zdarzenia w oknie wyszukiwania są kontrolowane przez system Android. Gdy użytkownik przesyła zapytanie, system przekazuje je do aktywności, którą określisz jako obsługującą wyszukiwania. Podczas wpisywania tekstu w oknie dialogowym mogą się też pojawiać sugestie wyszukiwania.

  • Widżet wyszukiwania to instancja elementu SearchView, którą możesz umieścić w dowolnym miejscu w układzie. Domyślnie widżet wyszukiwania zachowuje się jak standardowy widżet EditText i nie wykonuje żadnych działań, ale możesz go skonfigurować tak, aby system Android obsługiwał wszystkie zdarzenia wejściowe, przekazywał zapytania do odpowiedniej aktywności i wyświetlał sugestie wyszukiwania – tak jak okno wyszukiwania.

Gdy użytkownik przeprowadza wyszukiwanie w oknie wyszukiwania lub widżecie wyszukiwania, system tworzy obiekt Intent i zapisuje w nim zapytanie użytkownika. System uruchamia wtedy aktywność, którą deklarujesz do obsługi wyszukiwań – „aktywność umożliwiającą wyszukiwanie” – i przekazuje jej intencję. Aby skonfigurować aplikację pod kątem tego rodzaju wyszukiwania wspomaganego, musisz mieć:

  • konfiguracja wyszukiwania,
    Plik XML, który konfiguruje niektóre ustawienia okna lub widżetu wyszukiwania. Obejmuje ustawienia funkcji takich jak wyszukiwanie głosowe, sugestie wyszukiwania i tekst podpowiedzi w polu wyszukiwania.
  • Aktywność, którą można wyszukać
    Activity który otrzymuje zapytanie, przeszukuje dane i wyświetla wyniki wyszukiwania.
  • interfejs wyszukiwania udostępniany przez:
    • okno wyszukiwania,
      Domyślnie okno wyszukiwania jest ukryte. Pojawia się u góry ekranu, gdy dzwonisz onSearchRequested(), gdy użytkownik kliknie przycisk Szukaj.
    • Widżet SearchView
      Widżet wyszukiwania umożliwia umieszczenie pola wyszukiwania w dowolnym miejscu aktywności, w tym jako widoku działania na pasku aplikacji.

W dalszej części tego dokumentu dowiesz się, jak utworzyć konfigurację wyszukiwania i aktywność, którą można przeszukiwać, oraz jak wdrożyć interfejs wyszukiwania za pomocą okna wyszukiwania lub widżetu wyszukiwania.

Tworzenie konfiguracji z możliwością wyszukiwania

Najpierw potrzebujesz pliku XML zwanego konfiguracją wyszukiwania. Konfiguruje ona niektóre aspekty interfejsu okna lub widżetu wyszukiwania i określa sposób działania funkcji takich jak sugestie i wyszukiwanie głosowe. Ten plik ma tradycyjnie nazwę searchable.xml i musi być zapisany w katalogu projektu res/xml/.

Plik konfiguracji wyszukiwania musi zawierać element <searchable> jako węzeł główny i określać co najmniej 1 atrybut, jak pokazano w przykładzie poniżej:

<?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" >
</searchable>

Atrybut android:label jest jedynym wymaganym atrybutem. Wskazuje ona zasób tekstowy, który musi być nazwą aplikacji. Ta etykieta nie jest widoczna dla użytkownika, dopóki nie włączysz sugestii wyszukiwania w oknie szybkiego wyszukiwania. Wtedy etykieta będzie widoczna na liście elementów, które można wyszukiwać, w ustawieniach systemu.

Chociaż nie jest to wymagane, zalecamy zawsze uwzględnianie atrybutu android:hint, który zawiera ciąg podpowiedzi w polu wyszukiwania, zanim użytkownicy wpiszą zapytanie. Podpowiedź jest ważna, ponieważ dostarcza użytkownikom istotnych wskazówek dotyczących tego, czego mogą szukać.

Element <searchable> akceptuje kilka innych atrybutów. Większość atrybutów nie jest jednak potrzebna, dopóki nie dodasz funkcji takich jak sugestie wyszukiwania i wyszukiwanie głosowe. Szczegółowe informacje o pliku konfiguracji wyszukiwania znajdziesz w dokumencie referencyjnym Konfiguracja wyszukiwania.

Tworzenie aktywności z możliwością wyszukiwania

Wyszukiwalna aktywność to Activity w aplikacji, która wykonuje wyszukiwania na podstawie ciągu zapytania i wyświetla wyniki wyszukiwania.

Gdy użytkownik przeprowadzi wyszukiwanie w oknie lub widżecie wyszukiwania, system uruchomi aktywność z możliwością wyszukiwania i prześle do niej zapytanie w IntentACTION_SEARCH action. Aktywność, którą można przeszukiwać, pobiera zapytanie z dodatkowych informacji intencjiQUERY, a następnie przeszukuje Twoje dane i wyświetla wyniki.

Ponieważ okno wyszukiwania lub widżet możesz umieścić w dowolnej innej aktywności w aplikacji, system musi wiedzieć, która aktywność umożliwia wyszukiwanie, aby prawidłowo przekazywać zapytanie. Najpierw zadeklaruj aktywność, którą można wyszukiwać, w pliku manifestu Androida.

Deklarowanie aktywności, którą można wyszukać

Jeśli nie masz jeszcze takiego narzędzia, utwórz Activity, które wyszukuje informacje i wyświetla wyniki. Nie musisz jeszcze wdrażać funkcji wyszukiwania – wystarczy, że utworzysz działanie, które możesz zadeklarować w pliku manifestu. W elemencie <activity> pliku manifestu wykonaj te czynności:

  1. Zadeklaruj aktywność, aby zaakceptować intencję ACTION_SEARCH w elemencie <intent-filter>.
  2. Określ konfigurację wyszukiwania, która ma być używana w elemencie <meta-data>.

Pokazuje to poniższy przykład:

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...
</application>

Element <meta-data> musi zawierać atrybut android:name o wartości "android.app.searchable" i atrybut android:resource z odwołaniem do pliku konfiguracyjnego z możliwością wyszukiwania. W przykładzie powyżej odnosi się do pliku res/xml/searchable.xml.

Wyszukiwanie

Po zadeklarowaniu w pliku manifestu aktywności, w której można wyszukiwać, wykonaj te czynności, aby przeprowadzić w niej wyszukiwanie:

  1. Otrzymanie zapytania.
  2. Wyszukiwanie danych
  3. Przedstaw wyniki.

Odbieranie zapytania

Gdy użytkownik przeprowadzi wyszukiwanie w oknie dialogowym wyszukiwania lub w widżecie, system uruchomi aktywność z możliwością wyszukiwania i wyśle do niej ACTION_SEARCHintent. Ten zamiar zawiera zapytanie w dodatkowym ciągu QUERY. Sprawdź ten zamiar po rozpoczęciu aktywności i wyodrębnij ciąg znaków. Oto przykład, jak uzyskać zapytanie, gdy rozpoczyna się aktywność, którą można wyszukiwać:

Kotlin

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

    // Verify the action and get the query.
    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doMySearch(query)
        }
    }
}

Java

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

    // Get the intent, verify the action, and get the query.
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

Ciąg QUERY jest zawsze uwzględniany w przypadku intencji ACTION_SEARCH. W poprzednim przykładzie zapytanie jest pobierane i przekazywane do lokalnej metody doMySearch(), w której wykonywane jest właściwe wyszukiwanie.

Wyszukiwanie danych

Proces przechowywania i wyszukiwania danych jest unikalny dla Twojej aplikacji. Dane możesz przechowywać i wyszukiwać na wiele sposobów, a ten dokument nie pokazuje, jak to zrobić. Zastanów się, jak będziesz przechowywać i wyszukiwać dane, biorąc pod uwagę swoje potrzeby i format danych. Oto kilka wskazówek, które mogą Ci się przydać:

  • Jeśli dane są przechowywane w bazie danych SQLite na urządzeniu, przeprowadzenie wyszukiwania pełnotekstowego za pomocą FTS3 zamiast LIKEzapytaniaLIKE może zapewnić bardziej niezawodne wyszukiwanie w danych tekstowych i znacznie szybsze uzyskiwanie wyników. Więcej informacji o FTS3 znajdziesz na stronie sqlite.org, a o SQLite na Androidzie – w SQLiteDatabase.
  • Jeśli dane są przechowywane online, na postrzeganą wydajność wyszukiwania może mieć wpływ połączenie użytkownika z internetem. Możesz wyświetlać wskaźnik postępu, dopóki nie uzyskasz wyników wyszukiwania. Informacje o interfejsach API sieci znajdziesz w sekcji android.net , a o wyświetlaniu wskaźnika postępu – w sekcji ProgressBar.

Prezentowanie wyników

Niezależnie od tego, gdzie znajdują się Twoje dane i jak ich szukasz, zalecamy zwracanie wyników wyszukiwania do aktywności, w której można wyszukiwać, za pomocą znaku Adapter. W ten sposób możesz wyświetlić wszystkie wyniki wyszukiwania w RecyclerView. Jeśli dane pochodzą z zapytania do bazy danych SQLite, możesz zastosować wyniki do RecyclerView za pomocą CursorAdapter. Jeśli dane są w innym formacie, możesz utworzyć rozszerzenie BaseAdapter.

Adapter wiąże każdy element z zestawu danych z obiektem View. Gdy Adapter zostanie zastosowany do RecyclerView, każdy element danych zostanie wstawiony do listy jako osobny widok. Adapter to tylko interfejs, więc potrzebne są implementacje takie jak CursorAdapter, które służą do wiązania danych z Cursor. Jeśli żadne z dotychczasowych wdrożeń nie pasuje do Twoich danych, możesz wdrożyć własne rozwiązanie na podstawie BaseAdapter.

Korzystanie z okna wyszukiwania

W oknie wyszukiwania u góry ekranu znajduje się pływające pole wyszukiwania, a po lewej stronie ikona aplikacji. Podczas wpisywania tekstu w oknie wyszukiwania mogą pojawiać się sugestie wyszukiwania. Gdy użytkownik przeprowadza wyszukiwanie, system wysyła zapytanie do aktywności, która umożliwia wyszukiwanie i przeprowadza je.

Domyślnie okno wyszukiwania jest zawsze ukryte, dopóki użytkownik go nie aktywuje. Aplikacja może aktywować okno wyszukiwania, wywołując onSearchRequested(). Ta metoda nie będzie jednak działać, dopóki nie włączysz okna wyszukiwania dla aktywności.

Aby w oknie wyszukiwania można było przeprowadzać wyszukiwania, wskaż systemowi, które aktywności z możliwością wyszukiwania mają otrzymywać zapytania z tego okna. Na przykład w poprzedniej sekcji dotyczącej tworzenia aktywności z możliwością wyszukiwania utworzono aktywność z możliwością wyszukiwania o nazwie SearchableActivity. Jeśli chcesz, aby oddzielna aktywność, np. o nazwie OtherActivity, wyświetlała okno wyszukiwania i przekazywała wyszukiwania do SearchableActivity, zadeklaruj w pliku manifestu, że SearchableActivity jest aktywnością, która ma być używana do wyświetlania okna wyszukiwania w OtherActivity.

Aby zadeklarować aktywność, którą można wyszukiwać w oknie wyszukiwania aktywności, dodaj element <meta-data> w elemencie <activity> odpowiedniej aktywności. Element <meta-data> musi zawierać atrybut android:value, który określa nazwę klasy aktywności, w której można wyszukiwać, oraz atrybut android:name o wartości "android.app.default_searchable".

Oto na przykład deklaracja aktywności, którą można wyszukiwać, SearchableActivity, oraz innej aktywności, OtherActivity, która używa SearchableActivity do przeprowadzania wyszukiwań wykonywanych z jej okna wyszukiwania:

<application ... >
    <!-- This is the searchable activity; it performs searches. -->
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>

    <!-- This activity enables the search dialog to initiate searches
         in the SearchableActivity. -->
    <activity android:name=".OtherActivity" ... >
        <!-- Enable the search dialog to send searches to SearchableActivity. -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchableActivity" />
    </activity>
    ...
</application>

Ponieważ element OtherActivity zawiera teraz element <meta-data>, który deklaruje, jakiej aktywności związanej z wyszukiwaniem należy używać do wyszukiwania, aktywność ta włącza okno wyszukiwania. Chociaż użytkownik jest w tej aktywności, metoda onSearchRequested() aktywuje okno wyszukiwania. Gdy użytkownik przeprowadza wyszukiwanie, system uruchamia SearchableActivity i przekazuje mu ACTION_SEARCH intencję.

Jeśli chcesz, aby każda aktywność w aplikacji wyświetlała okno wyszukiwania, wstaw powyższy element <meta-data> jako element podrzędny elementu <application> zamiast każdego elementu <activity>. Dzięki temu każda aktywność dziedziczy wartość, udostępnia okno wyszukiwania i przekazuje wyszukiwania do tej samej aktywności, w której można wyszukiwać. Jeśli masz wiele aktywności, które można wyszukiwać, możesz zastąpić domyślną aktywność, którą można wyszukiwać, umieszczając inną deklarację <meta-data> w poszczególnych aktywnościach.

Po włączeniu okna wyszukiwania dla aktywności aplikacja jest gotowa do przeprowadzania wyszukiwań.

Wywoływanie okna wyszukiwania

Chociaż niektóre urządzenia mają specjalny przycisk wyszukiwania, jego działanie może się różnić w zależności od urządzenia. Wiele urządzeń nie ma w ogóle przycisku wyszukiwania. Dlatego podczas korzystania z okna wyszukiwania musisz udostępnić w interfejsie przycisk wyszukiwania, który aktywuje okno wyszukiwania przez wywołanie funkcji onSearchRequested().

Możesz na przykład dodać przycisk wyszukiwania w menu opcji lub układzie interfejsu, który wywołuje onSearchRequested().

Możesz też włączyć funkcję „pisanie w celu wyszukiwania”, która aktywuje okno dialogowe wyszukiwania, gdy użytkownik zacznie pisać na klawiaturze. Wpisane znaki zostaną wstawione w oknie wyszukiwania. Aby włączyć wpisywanie w celu wyszukiwania w aktywności, wywołaj setDefaultKeyMode— lub DEFAULT_KEYS_SEARCH_LOCAL— podczas wykonywania metody onCreate() aktywności.

Wpływ okna wyszukiwania na cykl życia działania

Okno wyszukiwania jest elementem DialogpływającymDialog u góry ekranu. Nie powoduje to żadnych zmian w stosie działań, więc gdy pojawi się okno wyszukiwania, nie są wywoływane żadne metody cyklu życia, takie jak onPause(). Aktywność traci fokus, ponieważ jest on przekazywany do okna wyszukiwania.

Jeśli chcesz otrzymywać powiadomienia o aktywacji okna wyszukiwania, zastąp metodę onSearchRequested(). Gdy system wywoła tę metodę, oznacza to, że Twoja aktywność traci fokus wejściowy na rzecz okna wyszukiwania, więc możesz wykonać dowolne działanie odpowiednie dla tego zdarzenia, np. wstrzymać grę. O ile nie przekazujesz danych kontekstu wyszukiwania (omówionych w innej sekcji tego dokumentu), zakończ metodę, wywołując implementację klasy nadrzędnej:

Kotlin

override fun onSearchRequested(): Boolean {
    pauseSomeStuff()
    return super.onSearchRequested()
}

Java

@Override
public boolean onSearchRequested() {
    pauseSomeStuff();
    return super.onSearchRequested();
}

Jeśli użytkownik anuluje wyszukiwanie, klikając przycisk Wstecz, okno wyszukiwania zostanie zamknięte, a aktywność odzyska fokus. Możesz zarejestrować się, aby otrzymywać powiadomienia o zamknięciu okna wyszukiwania za pomocą setOnDismissListener(), setOnCancelListener() lub obu tych metod. Wystarczy zarejestrować zdarzenie OnDismissListener, ponieważ jest ono wywoływane za każdym razem, gdy zamykane jest okno wyszukiwania. OnCancelListener Dotyczy tylko zdarzeń, w których użytkownik wyraźnie zamyka okno wyszukiwania, więc nie jest wywoływane podczas wyszukiwania. Po wykonaniu wyszukiwania okno wyszukiwania automatycznie znika.

Jeśli bieżąca aktywność nie jest aktywnością, w której można wyszukiwać, po wykonaniu wyszukiwania przez użytkownika wywoływane są normalne zdarzenia cyklu życia aktywności – bieżąca aktywność otrzymuje onPause(), jak opisano w Wprowadzeniu do aktywności. Jeśli jednak bieżąca aktywność jest aktywnością, którą można wyszukiwać, nastąpi jedna z tych sytuacji:

  • Domyślnie aktywność, w której można wyszukiwać, otrzymuje intencję ACTION_SEARCH z wywołaniem onCreate(), a nowa instancja aktywności jest przenoszona na początek stosu aktywności. W stosie działań znajdują się teraz 2 instancje aktywności z możliwością wyszukiwania, więc kliknięcie przycisku Wstecz powoduje powrót do poprzedniej instancji aktywności z możliwością wyszukiwania, a nie zamknięcie tej aktywności.
  • Jeśli ustawisz wartość android:launchMode na "singleTop", wyszukiwalna aktywność otrzyma intencję ACTION_SEARCH z wywołaniem onNewIntent(Intent), przekazującą nową intencję ACTION_SEARCH. Oto przykład, jak możesz sobie poradzić w takiej sytuacji, w której tryb uruchamiania aktywności, którą można wyszukiwać, to "singleTop":

    Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.search)
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                doMySearch(query)
            }
        }
    }

    Java

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);
        handleIntent(getIntent());
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }
    
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    W porównaniu z przykładowym kodem w sekcji dotyczącej przeprowadzania wyszukiwania cały kod do obsługi zamiaru wyszukiwania znajduje się teraz w metodzie handleIntent(), dzięki czemu mogą go wykonywać zarówno onCreate(), jak i onNewIntent().

    Gdy system wywołuje metodę onNewIntent(Intent), aktywność nie jest ponownie uruchamiana, więc metoda getIntent() zwraca ten sam zamiar, który został odebrany za pomocą metody onCreate(). Dlatego musisz wywołać funkcję setIntent(Intent) w funkcji onNewIntent(Intent), aby intencja zapisana przez aktywność została zaktualizowana na wypadek, gdyby w przyszłości wywołać funkcję getIntent().

Drugi scenariusz, w którym używany jest "singleTop"tryb uruchamiania, jest zwykle preferowany, ponieważ po zakończeniu wyszukiwania użytkownik może przeprowadzić dodatkowe wyszukiwania, a nie chcesz, aby aplikacja tworzyła wiele instancji działania, w którym można wyszukiwać. Zalecamy ustawienie trybu uruchamiania wyszukiwalnej aktywności na "singleTop" w pliku manifestu aplikacji, jak pokazano w tym przykładzie:

<activity android:name=".SearchableActivity"
          android:launchMode="singleTop" >
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
          android:name="android.app.searchable"
          android:resource="@xml/searchable"/>
  </activity>

Przekazywanie danych kontekstu wyszukiwania

W niektórych przypadkach możesz wprowadzać niezbędne zmiany w zapytaniu w ramach aktywności, w której można wyszukiwać, za każdym razem, gdy wyszukujesz. Jeśli jednak chcesz doprecyzować kryteria wyszukiwania na podstawie aktywności, z której użytkownik przeprowadza wyszukiwanie, możesz podać dodatkowe dane w intencji, którą system wysyła do Twojej aktywności umożliwiającej wyszukiwanie. Dodatkowe dane możesz przekazywać w parametrze APP_DATA Bundle, który jest uwzględniony w intencji ACTION_SEARCH.

Aby przekazać tego rodzaju dane do aktywności, w której można wyszukiwać, zastąp metodę onSearchRequested() w aktywności, w której użytkownik może wyszukiwać, utwórz obiekt Bundle z dodatkowymi danymi i wywołaj metodę startSearch() , aby aktywować okno wyszukiwania. Przykład:

Kotlin

override fun onSearchRequested(): Boolean {
    val appData = Bundle().apply {
        putBoolean(JARGON, true)
    }
    startSearch(null, false, appData, false)
    return true
}

Java

@Override
public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

Wartość „true” oznacza, że udało Ci się obsłużyć to zdarzenie wywołania zwrotnego i wywołać funkcję startSearch(), aby aktywować okno wyszukiwania. Gdy użytkownik prześle zapytanie, zostanie ono dostarczone do Twojej aktywności z możliwością wyszukiwania wraz z dodanymi przez Ciebie danymi. Aby zawęzić wyszukiwanie, możesz wyodrębnić dodatkowe dane z APP_DATA Bundle, jak pokazano w tym przykładzie:

Kotlin

val jargon: Boolean = intent.getBundleExtra(SearchManager.APP_DATA)?.getBoolean(JARGON) ?: false

Java

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

Korzystanie z widżetu wyszukiwania

Obraz przedstawiający widok wyszukiwania na górnym pasku aplikacji

Rysunek 1. SearchViewWidżet jako widok działania na pasku aplikacji.

Widżet wyszukiwania zapewnia taką samą funkcjonalność jak okno wyszukiwania. Uruchamia odpowiednią aktywność, gdy użytkownik przeprowadza wyszukiwanie, a także może wyświetlać sugestie wyszukiwania i przeprowadzać wyszukiwanie głosowe. Jeśli nie możesz umieścić widżetu wyszukiwania na pasku aplikacji, możesz go umieścić w układzie aktywności.

Konfigurowanie widżetu wyszukiwania

Po utworzeniu konfiguracji wyszukiwaniaaktywności, którą można przeszukiwać, włącz wyszukiwanie z asystą dla każdego SearchView, wywołując funkcję setSearchableInfo() i przekazując jej obiekt SearchableInfo reprezentujący konfigurację, którą można przeszukiwać.

Możesz uzyskać odwołanie do SearchableInfo, wywołując getSearchableInfo() na SearchManager.

Jeśli na przykład używasz SearchView jako widoku działania na pasku aplikacji, włącz widżet podczas wywołania zwrotnego onCreateOptionsMenu(), jak pokazano w tym przykładzie:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the options menu from XML.
    val inflater = menuInflater
    inflater.inflate(R.menu.options_menu, menu)

    // Get the SearchView and set the searchable configuration.
    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    (menu.findItem(R.id.menu_search).actionView as SearchView).apply {
        // Assumes current activity is the searchable activity.
        setSearchableInfo(searchManager.getSearchableInfo(componentName))
        setIconifiedByDefault(false) // Don't iconify the widget. Expand it by default.
    }

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu from XML.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Get the SearchView and set the searchable configuration.
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Assumes current activity is the searchable activity.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Don't iconify the widget. Expand it by default.

    return true;
}

Widżet wyszukiwania jest teraz skonfigurowany, a system dostarcza zapytania do Twojej aktywności z możliwością wyszukiwania. Możesz też włączyć propozycje wyszukiwania w widżecie wyszukiwania.

Więcej informacji o widokach działań na pasku aplikacji znajdziesz w artykule Korzystanie z widoków działań i dostawców działań.

Inne funkcje widżetu wyszukiwania

SearchView widżet udostępnia kilka dodatkowych funkcji, które mogą Ci się przydać:

przycisk przesyłania,
Domyślnie nie ma przycisku przesyłania zapytania, więc użytkownik musi nacisnąć klawisz Return na klawiaturze, aby rozpocząć wyszukiwanie. Przycisk „Prześlij” możesz dodać, wywołując funkcję setSubmitButtonEnabled(true).
Zawężanie zapytań w sugestiach wyszukiwania
Gdy włączysz sugestie wyszukiwania, zwykle oczekujesz, że użytkownicy wybiorą podpowiedź, ale mogą też chcieć doprecyzować sugerowane zapytanie. Możesz dodać przycisk obok każdej sugestii, który wstawia ją do pola wyszukiwania, aby użytkownik mógł ją doprecyzować, wywołując funkcję setQueryRefinementEnabled(true).
możliwość przełączania widoczności pola wyszukiwania;
Domyślnie widżet wyszukiwania jest „zminimalizowany”, co oznacza, że jest reprezentowany tylko przez ikonę wyszukiwania – lupę. Po dotknięciu ikony przez użytkownika rozwija się i wyświetla pole wyszukiwania. Jak pokazano w przykładzie powyżej, możesz domyślnie wyświetlać pole wyszukiwania, wywołując funkcję setIconifiedByDefault(false). Możesz też przełączać wygląd widżetu wyszukiwania, wywołując funkcję setIconified().

Istnieje kilka innych interfejsów API w klasie SearchView, które umożliwiają dostosowanie widżetu wyszukiwania. Większość z nich jest jednak używana tylko wtedy, gdy samodzielnie obsługujesz wszystkie dane wejściowe użytkownika, zamiast korzystać z systemu Android do dostarczania zapytań i wyświetlania sugestii wyszukiwania.

Korzystanie zarówno z widżetu, jak i okna

Jeśli wstawisz widżet wyszukiwania na pasku aplikacji jako widok działania i włączysz jego wyświetlanie na pasku aplikacji, jeśli jest na nim miejsce – ustawiając android:showAsAction="ifRoom" – widżet wyszukiwania może nie pojawić się jako widok działania. Zamiast tego pozycja menu może pojawić się w menu dodatkowym. Na przykład, gdy aplikacja jest uruchomiona na mniejszym ekranie, na pasku aplikacji może nie być wystarczająco dużo miejsca, aby wyświetlić widżet wyszukiwania wraz z innymi elementami działania lub elementami nawigacyjnymi, więc element menu pojawia się w menu przepełnienia. Gdy element znajduje się w rozszerzonym menu, działa jak zwykła pozycja menu i nie wyświetla widoku działania, czyli widżetu wyszukiwania.

Aby sobie z tym poradzić, pozycja menu, do której dołączasz widżet wyszukiwania, musi aktywować okno wyszukiwania, gdy użytkownik wybierze ją z rozszerzonego menu. Aby to zrobić, zaimplementuj onOptionsItemSelected() do obsługi elementu menu „Szukaj” i otwórz okno wyszukiwania, wywołując onSearchRequested().

Więcej informacji o działaniu elementów na pasku aplikacji i o tym, jak sobie z tym poradzić, znajdziesz w artykule Dodawanie paska aplikacji.

Dodawanie wyszukiwania głosowego

Aby dodać funkcję wyszukiwania głosowego do okna wyszukiwania lub widżetu, dodaj atrybut android:voiceSearchMode do konfigurowalnego elementu wyszukiwania. Dodaje to przycisk wyszukiwania głosowego, który uruchamia prompt głosowy. Gdy użytkownik skończy mówić, transkrypcja zapytania jest wysyłana do Twojej aktywności, w której można wyszukiwać.

Pokazuje to poniższy przykład:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable>

Wartość showVoiceSearchButton jest wymagana, aby włączyć wyszukiwanie głosowe. Druga wartość, launchRecognizer, określa, że przycisk wyszukiwania głosowego musi uruchamiać rozpoznawanie, które zwraca transkrybowany tekst do aktywności umożliwiającej wyszukiwanie.

Możesz podać dodatkowe atrybuty, aby określić zachowania związane z wyszukiwaniem głosowym, np. oczekiwany język i maksymalną liczbę wyników do zwrócenia. Więcej informacji o dostępnych atrybutach znajdziesz w artykule Konfiguracja wyszukiwania.

Dodawanie sugestii wyszukiwania

Zarówno okno wyszukiwania, jak i widżet wyszukiwania mogą wyświetlać sugestie wyszukiwania podczas wpisywania tekstu przez użytkownika, z pomocą systemu Android. System zarządza listą sugestii i obsługuje zdarzenie, gdy użytkownik wybierze sugestię.

Możesz podać 2 rodzaje sugestii wyszukiwania:

Sugestie wyszukiwania na podstawie ostatnich zapytań
Te sugestie to słowa, których użytkownik wcześniej używał jako zapytań w wyszukiwarce w Twojej aplikacji. Więcej informacji znajdziesz w artykule Dodawanie niestandardowych sugestii wyszukiwania.
Niestandardowe sugestie wyszukiwania
Są to sugestie wyszukiwania, które pochodzą z Twojego źródła danych i pomagają użytkownikom od razu wybrać prawidłową pisownię lub szukany element. Więcej informacji znajdziesz w artykule Dodawanie niestandardowych sugestii wyszukiwania.