Thiết lập giao diện tìm kiếm

Bạn nên sử dụng tiện ích SearchView làm một mục trên thanh ứng dụng để cung cấp chức năng tìm kiếm trong ứng dụng của mình. Giống như tất cả các mục trên thanh ứng dụng, bạn có thể xác định SearchView để mọi lúc hoặc chỉ khi có chỗ. Bạn cũng có thể xác định đây là thao tác có thể thu gọn, thao tác này hiển thị SearchView dưới dạng biểu tượng ngay từ đầu, sau đó chiếm toàn bộ thanh ứng dụng làm trường tìm kiếm khi người dùng nhấn vào biểu tượng đó.

Thêm SearchView vào thanh ứng dụng

Để thêm tiện ích SearchView vào thanh ứng dụng, hãy tạo một tệp trong dự án có tên res/menu/options_menu.xml và thêm mã sau vào tệp đó. Mã này xác định cách tạo mục tìm kiếm, chẳng hạn như biểu tượng sử dụng và tiêu đề của mục. Thuộc tính collapseActionView cho phép SearchView mở rộng để chiếm toàn bộ thanh ứng dụng và thu gọn về một mục trên thanh ứng dụng thông thường khi không được sử dụng. Do không gian thanh ứng dụng trên điện thoại di động bị hạn chế, bạn nên sử dụng thuộc tính collapsibleActionView để mang lại trải nghiệm người dùng tốt hơn.

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

Nếu bạn muốn biểu tượng tìm kiếm dễ truy cập hơn, hãy tạo tệp ic_search.xml trong thư mục /res/drawable và đưa mã sau vào tệp đó:

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

Để hiển thị SearchView trên thanh ứng dụng, hãy tăng cường tài nguyên trình đơn XML res/menu/options_menu.xml trong phương thức onCreateOptionsMenu() của hoạt động:

Kotlin

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

    return true
}

Việc chạy ứng dụng sẽ tạo ra nội dung như sau:

Hình ảnh cho thấy một màn hình trống kèm theo biểu tượng tìm kiếm trong thanh trên cùng của ứng dụng
Hình 1. Biểu tượng tìm kiếm trong thanh trên cùng của ứng dụng.

SearchView xuất hiện trên thanh ứng dụng của ứng dụng nhưng không hoạt động. Nếu nhấn vào biểu tượng tìm kiếm, bạn sẽ thấy như sau:

Hình ảnh minh hoạ cách hoạt động của chế độ xem tìm kiếm
Hình 2. SearchView trong thực tế.

Để SearchView hoạt động, bạn phải xác định cách SearchView hoạt động.

Tạo cấu hình tìm kiếm

Cấu hình tìm kiếm chỉ định hành vi của SearchView và được xác định trong tệp res/xml/searchable.xml. Cấu hình tìm kiếm phải chứa ít nhất một thuộc tính android:label có cùng giá trị với thuộc tính android:label của phần tử <application> hoặc <activity> trong tệp kê khai Android. Tuy nhiên, bạn cũng nên thêm thuộc tính android:hint để cho người dùng biết nội dung cần nhập vào hộp tìm kiếm.

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

Trong tệp kê khai của ứng dụng, hãy khai báo một phần tử <meta-data> trỏ đến tệp res/xml/searchable.xml. Khai báo phần tử trong <activity> mà bạn muốn hiển thị 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>

Trong phương thức onCreateOptionsMenu() mà bạn tạo, hãy liên kết cấu hình tìm kiếm với SearchView bằng cách gọi 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
}

Lệnh gọi đến getSearchableInfo() sẽ nhận đối tượng SearchableInfo được tạo từ tệp XML cấu hình tìm kiếm. Khi cấu hình tìm kiếm được liên kết đúng cách với SearchView và người dùng gửi một truy vấn, SearchView sẽ bắt đầu một hoạt động bằng ý định ACTION_SEARCH. Sau đó, bạn cần một hoạt động có thể lọc ý định này và xử lý cụm từ tìm kiếm.

Tạo hoạt động có thể tìm kiếm

Một bộ lọc hoạt động có thể tìm kiếm cho ý định ACTION_SEARCH và tìm kiếm truy vấn trong một tập dữ liệu. Để tạo một hoạt động có thể tìm kiếm, hãy khai báo một hoạt động mà bạn chọn để lọc ý định ACTION_SEARCH:

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

Trong hoạt động có thể tìm kiếm, hãy xử lý ý định ACTION_SEARCH bằng cách kiểm tra ý định đó trong phương thức 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")
        }
    }
}

Giờ đây, SearchView có thể chấp nhận truy vấn của người dùng và bắt đầu hoạt động có thể tìm kiếm bằng ý định ACTION_SEARCH.

Sau khi nhận được cụm từ tìm kiếm, bạn có thể truyền cụm từ đó đến ViewModel. Tại đây, bạn có thể sử dụng cụm từ đó trong các lớp khác của cấu trúc để truy xuất kết quả tìm kiếm cần hiển thị.