Konfigurowanie interfejsu wyszukiwania

Zalecamy korzystanie z widżetu SearchView jako elementu na pasku aplikacji, aby umożliwić wyszukiwanie w aplikacji. Tak jak w przypadku wszystkich elementów na pasku aplikacji, możesz określić element SearchView, który ma się wyświetlać zawsze lub tylko wtedy, gdy jest dość wolnego miejsca. Możesz też zdefiniować je jako działanie zwijane. Gdy użytkownik kliknie ikonę, najpierw wyświetla SearchView jako ikonę, a potem zajmuje cały pasek aplikacji jako pole wyszukiwania.

Dodawanie obiektu SearchView do paska aplikacji

Aby dodać widżet SearchView do paska aplikacji, utwórz w projekcie plik o nazwie res/menu/options_menu.xml i dodaj do niego poniższy kod. Ten kod określa sposób tworzenia elementu wyszukiwania, np. ikonę, której należy użyć, oraz tytuł elementu. Atrybut collapseActionView pozwala elementowi SearchView rozwijać się, aby zajmować cały pasek aplikacji, a gdy nie jest używany, z powrotem zwija się do zwykłego elementu na pasku aplikacji. Ze względu na ograniczoną ilość miejsca na pasku aplikacji na słuchawkach zalecamy korzystanie z atrybutu collapsibleActionView, aby zwiększyć wygodę użytkowników.

<?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>

Jeśli chcesz, aby ikona wyszukiwania była bardziej dostępna, utwórz w folderze /res/drawable plik ic_search.xml i umieść w nim ten kod:

<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>

Aby wyświetlić SearchView na pasku aplikacji, prześlij zasób menu XML res/menu/options_menu.xml w metodzie onCreateOptionsMenu() w aktywności:

Kotlin

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

    return true
}

Uruchomienie aplikacji wygeneruje coś takiego:

Obraz przedstawiający pusty ekran z ikoną wyszukiwania na górnym pasku aplikacji
Rysunek 1. Ikona wyszukiwania na górnym pasku aplikacji

Ikona SearchView pojawia się na pasku aplikacji aplikacji, ale nie działa. Gdy klikniesz ikonę wyszukiwania, zobaczysz coś takiego:

Obraz pokazujący działanie wyszukiwarki
Rysunek 2. SearchView w praktyce.

Aby element SearchView działał, musisz określić sposób jego działania.SearchView

Tworzenie konfiguracji wyszukiwania

Konfiguracja wyszukiwania określa sposób zachowania SearchView i jest zdefiniowana w pliku res/xml/searchable.xml. Konfiguracja wyszukiwania musi zawierać co najmniej atrybut android:label o tej samej wartości co atrybut android:label elementu <application> lub <activity> w pliku manifestu Androida. Zalecamy jednak również dodanie atrybutu android:hint, aby użytkownik wiedział, co wpisać w polu wyszukiwania.

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

W pliku manifestu aplikacji zadeklaruj element <meta-data>, który wskazuje plik res/xml/searchable.xml. Zadeklaruj element w elemencie <activity>, w którym chcesz wyświetlać 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>

W utworzonej metodzie onCreateOptionsMenu() powiąż konfigurację wyszukiwania z SearchView, wywołując setSearchableInfo(SearchableInfo):

Kotlin

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
}

Wywołanie getSearchableInfo() pobiera obiekt SearchableInfo utworzony z pliku XML konfiguracji wyszukiwania. Gdy konfiguracja wyszukiwania jest prawidłowo powiązana z elementem SearchView, a użytkownik prześle zapytanie, SearchView rozpocznie działanie z intencją ACTION_SEARCH. Następnie potrzebujesz działania, które będzie odfiltrowywać tę intencję i obsługiwać wyszukiwane hasło.

Utwórz aktywność, którą można przeszukiwać

Aktywność, którą można przeszukiwać, filtruje na potrzeby intencji ACTION_SEARCH i wyszukuje zapytanie w zbiorze danych. Aby utworzyć działanie dostępne do przeszukiwania, zadeklaruj wybraną aktywność w celu odfiltrowania intencji ACTION_SEARCH:

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

W aktywności, którą można przeszukiwać, rozpoznaj intencję ACTION_SEARCH, sprawdzając ją w metodzie onCreate().

Kotlin

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")
        }
    }
}

Teraz SearchView może zaakceptować zapytanie użytkownika i rozpocząć Twoją aktywność związaną z wyszukiwaniem za pomocą intencji ACTION_SEARCH.

Po otrzymaniu zapytania możesz je przekazać do interfejsu ViewModel, gdzie możesz używać go w innych warstwach swojej architektury do pobierania wyników wyszukiwania do wyświetlenia.