Konfigurowanie interfejsu wyszukiwania

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

Aby zapewnić w aplikacji funkcję wyszukiwania, zalecamy używanie widżetu SearchView jako elementu paska aplikacji. Podobnie jak w przypadku wszystkich elementów paska aplikacji możesz zdefiniować SearchView tak, aby wyświetlał się przez cały czas lub tylko wtedy, gdy jest na to miejsce. Możesz też zdefiniować go jako działanie zwijane, które początkowo wyświetla SearchView jako ikonę, a następnie zajmuje cały pasek aplikacji jako pole wyszukiwania, gdy użytkownik kliknie ikonę.

Dodawanie 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 ten kod. Ten kod określa, jak utworzyć element wyszukiwania, np. ikonę i tytuł elementu. Atrybut collapseActionView umożliwia rozszerzenie SearchView tak, aby zajmował cały pasek aplikacji, a gdy nie jest używany, zwijał się do normalnego elementu paska aplikacji. Ze względu na ograniczoną ilość miejsca na pasku aplikacji na urządzeniach mobilnych zalecamy używanie atrybutu collapsibleActionView, aby zapewnić lepsze wrażenia użytkownika.

<?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 plik ic_search.xml w folderze /res/drawable i dodaj do niego 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, rozwiń zasób menu XML res/menu/options_menu.xml w metodzie onCreateOptionsMenu() aktywności:

Kotlin

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

    return true
}

Po uruchomieniu aplikacji zobaczysz coś takiego:

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

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

Ilustracja przedstawiająca widok wyszukiwania w trakcie działania
Rysunek 2. SearchView w akcji.

Aby SearchView działał, musisz określić jego zachowanie.SearchView

Tworzenie konfiguracji wyszukiwania

Konfiguracja wyszukiwania określa, jak działa SearchView, i jest zdefiniowana w pliku res/xml/searchable.xml. Konfiguracja wyszukiwania musi zawierać co najmniej atrybut android:label, który ma taką samą wartość jak atrybut android:label elementu <application> lub <activity> w manifeście Androida. Zalecamy jednak 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 <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() powoduje uzyskanie obiektu SearchableInfo , który jest tworzony na podstawie pliku XML konfiguracji wyszukiwania. Gdy konfiguracja wyszukiwania jest prawidłowo powiązana z SearchView, a użytkownik prześle zapytanie, SearchView uruchomi aktywność z intencją ACTION_SEARCH. Potrzebujesz wtedy aktywności, która może filtrować tę intencję i obsługiwać zapytanie.

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

Aktywność z możliwością wyszukiwania filtruje intencję ACTION_SEARCH i wyszukuje zapytanie w zbiorze danych. Aby utworzyć aktywność z możliwością wyszukiwania, zadeklaruj wybraną aktywność, aby filtrować intencję ACTION_SEARCH:

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

W aktywności z możliwością wyszukiwania obsłuż 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 akceptować zapytanie użytkownika i uruchamiać aktywność z możliwością wyszukiwania z intencją ACTION_SEARCH.

Po uzyskaniu zapytania możesz przekazać je do ViewModel, gdzie możesz użyć go w innych warstwach architektury, aby pobrać wyniki wyszukiwania do wyświetlenia.