設定搜尋介面

建議您在應用程式列中使用 SearchView 小工具做為項目,以便在應用程式中提供搜尋功能。與應用程式列中的所有項目一樣,您可以定義 SearchView 一律顯示,或只在空房時顯示。您也可以將其定義為可收合動作,此動作會先將 SearchView 顯示為圖示,然後在使用者輕觸圖示時,將整個應用程式列做為搜尋欄位。

在應用程式列新增 SearchView

如要在應用程式列中加入 SearchView 小工具,請在專案中建立名為 res/menu/options_menu.xml 的檔案,並將下列程式碼加入該檔案。這段程式碼定義如何建立搜尋項目,例如要使用的圖示和項目名稱。collapseActionView 屬性可讓 SearchView 展開以顯示整個應用程式列,並在不使用時,收合為一般應用程式列項目。由於手機裝置上的應用程式列空間有限,建議您使用 collapsibleActionView 屬性,以便提供更優質的使用者體驗。

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

如果需要更易於存取的搜尋圖示,請在 /res/drawable 資料夾中建立 ic_search.xml 檔案,並在其中加入下列程式碼:

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

如要在應用程式列中顯示 SearchView,請在活動的 onCreateOptionsMenu() 方法中加載 XML 選單資源 res/menu/options_menu.xml

Kotlin

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

    return true
}

執行應用程式時,會產生類似下方的內容:

圖片顯示空白畫面,應用程式頂端列有一個搜尋圖示
圖 1. 應用程式頂端列中的搜尋圖示。

SearchView 會顯示在應用程式的應用程式列,但功能無法運作。輕觸搜尋圖示後,就會看到類似下方的內容:

顯示搜尋檢視畫面實際運作的圖片
圖 2. SearchView 實際運作。

如要讓 SearchView 正常運作,您必須定義 SearchView 的行為。

建立搜尋設定

搜尋設定會指定 SearchView 的行為,並在 res/xml/searchable.xml 檔案中定義。搜尋設定至少必須包含與 Android 資訊清單中 <application><activity> 元素的 android:label 屬性相同的 android:label 屬性。不過,我們也建議您新增 android:hint 屬性,讓使用者知道要在搜尋框中輸入哪些內容。

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

在應用程式的資訊清單檔案中,宣告指向 res/xml/searchable.xml 檔案的 <meta-data> 元素。在要顯示 SearchView<activity> 中宣告元素。

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

在您建立的 onCreateOptionsMenu() 方法中,呼叫 setSearchableInfo(SearchableInfo) 將搜尋設定與 SearchView 建立關聯:

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
}

呼叫 getSearchableInfo() 可取得從搜尋設定 XML 檔案建立的 SearchableInfo 物件。當搜尋設定正確與您的 SearchView 建立關聯,且使用者提交查詢之後,SearchView 就會用 ACTION_SEARCH 意圖啟動活動。您接著需要可以篩選此意圖的活動並處理搜尋查詢。

建立可供搜尋的活動

可搜尋的 ACTION_SEARCH 意圖活動篩選器,並在資料集內搜尋該查詢。如要建立可供搜尋的活動,請宣告您要篩選 ACTION_SEARCH 意圖的活動:

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

在可搜尋的活動中,在 onCreate() 方法中檢查 ACTION_SEARCH 意圖以處理此意圖。

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

現在,SearchView 可接受使用者的查詢,並使用 ACTION_SEARCH 意圖啟動可搜尋的活動。

取得搜尋查詢後,您可以將其傳送至 ViewModel,即可在架構的其他層使用該查詢來擷取要顯示的搜尋結果。