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

Bạn nên sử dụng SearchView dưới dạng 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 bạn. Như cho tất cả các mục trên thanh ứng dụng, bạn có thể xác định SearchView thành hiển thị mọi lúc hoặc chỉ khi có chỗ. Bạn cũng có thể xác định AdSense là một thao tác có thể thu gọn, hiển thị SearchView dưới dạng một biểu tượng ban đầ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 một 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ặt hàng. 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 trở lại thành mục trên thanh ứng dụng thông thường khi không sử dụng. Do không gian thanh ứng dụng hạn chế trên điện thoại di động, chúng tôi khuyên bạn nên sử dụng Thuộc tính collapsibleActionView để cải thiện trải nghiệm người dùng của bạ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 một biểu tượng tìm kiếm dễ tiếp cận hơn, hãy tạo một ic_search.xml tệp trong thư mục /res/drawable và đưa mã sau vào trong:

<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 SearchView trong thanh ứng dụng, hãy tăng cường trình đơn XML tài nguyên res/menu/options_menu.xml trong phần onCreateOptionsMenu() của hoạt động của bạn:

Kotlin

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

    return true
}

Khi chạy, ứng dụng sẽ tạo ra như sau:

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

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

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

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

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

Tìm kiếm cấu hình chỉ định cách hoạt động của SearchView và được xác định trong tệp res/xml/searchable.xml. Cấu hình tìm kiếm tối thiểu phải chứa một thuộc tính android:label có có cùng giá trị với thuộc tính android:label của <ứng dụng> hoặc <activity> trong tệp kê khai Android của bạn. Tuy nhiên, bạn cũng nên thêm Thuộc tính android:hint để giúp người dùng biết cần nhập nội dung gì 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 <meta-data> trỏ đến tệp res/xml/searchable.xml. Khai báo trong <activity> mà bạn muốn hiển thị phần tử 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
}

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

Tạo một 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 hoạt động bạn chọn để lọc cho ACTION_SEARCH ý định:

<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 để tìm kiếm thông tin này trong 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 truy vấn tìm kiếm, bạn có thể chuyển nó vào ViewModel, nơi bạn có thể sử dụng dữ liệu này trong các lớp khác của cấu trúc này để truy xuất kết quả tìm kiếm cần hiển thị.