Thêm cụm từ tìm kiếm được đề xuất tuỳ chỉnh

Thử cách Compose
Jetpack Compose là bộ công cụ giao diện người dùng được đề xuất cho Android. Tìm hiểu cách thêm chức năng tìm kiếm trong Compose.

Bạn có thể cung cấp các đề xuất tìm kiếm dựa trên các cụm từ tìm kiếm gần đây trong hộp thoại tìm kiếm hoặc tiện ích tìm kiếm trên Android. Ví dụ: nếu người dùng tìm kiếm "chó con", thì cụm từ tìm kiếm đó sẽ xuất hiện dưới dạng đề xuất khi họ nhập lại cụm từ tìm kiếm đó. Hình 1 minh hoạ ví dụ về một hộp thoại tìm kiếm có các đề xuất về cụm từ tìm kiếm gần đây.

Trước khi bắt đầu, hãy triển khai hộp thoại tìm kiếm hoặc một tiện ích tìm kiếm cho các hoạt động tìm kiếm cơ bản trong ứng dụng của bạn. Để tìm hiểu cách thực hiện, hãy xem bài viết Tạo giao diện tìm kiếm.

Thông tin cơ bản

Hình 1. Ảnh chụp màn hình hộp thoại tìm kiếm có các đề xuất truy vấn gần đây.

Đề xuất từ cụm từ tìm kiếm gần đây là những cụm từ tìm kiếm đã lưu. Khi người dùng chọn một đề xuất, hoạt động có thể tìm kiếm của bạn sẽ nhận được một ý định ACTION_SEARCH với đề xuất đó làm cụm từ tìm kiếm mà hoạt động có thể tìm kiếm của bạn đã xử lý.

Để cung cấp các đề xuất từ cụm từ tìm kiếm gần đây, bạn cần:

  • Triển khai một hoạt động có thể tìm kiếm.
  • Tạo một trình cung cấp nội dung mở rộng SearchRecentSuggestionsProvider và khai báo trình cung cấp đó trong tệp kê khai ứng dụng.
  • Sửa đổi cấu hình có thể tìm kiếm bằng thông tin về nhà cung cấp nội dung cung cấp các cụm từ tìm kiếm được đề xuất.
  • Lưu các truy vấn vào trình cung cấp nội dung của bạn mỗi khi một lượt tìm kiếm được thực hiện.

Giống như hệ thống Android hiển thị hộp thoại tìm kiếm, hệ thống này cũng hiển thị các đề xuất tìm kiếm bên dưới hộp thoại hoặc tiện ích tìm kiếm. Bạn cung cấp nguồn mà hệ thống sẽ truy xuất các đề xuất.

Khi hệ thống xác định rằng hoạt động của bạn có thể tìm kiếm và đưa ra các đề xuất tìm kiếm, thì điều sau đây sẽ xảy ra khi người dùng nhập một cụm từ tìm kiếm:

  1. Hệ thống sẽ lấy văn bản cụm từ tìm kiếm (bất kể người dùng bắt đầu nhập nội dung gì) và thực hiện một truy vấn đến trình cung cấp nội dung chứa các đề xuất của bạn.
  2. Nhà cung cấp nội dung của bạn trả về một Cursor trỏ đến tất cả các đề xuất khớp với văn bản cụm từ tìm kiếm.
  3. Hệ thống sẽ hiển thị danh sách các đề xuất do Cursor cung cấp.

Sau khi các cụm từ tìm kiếm đề xuất gần đây xuất hiện, có thể xảy ra những trường hợp sau:

  • Nếu người dùng nhập một khoá khác hoặc thay đổi cụm từ tìm kiếm theo bất kỳ cách nào, các bước trước đó sẽ được lặp lại và danh sách đề xuất sẽ được cập nhật.
  • Nếu người dùng thực hiện tìm kiếm, các đề xuất sẽ bị bỏ qua và cụm từ tìm kiếm sẽ được gửi đến hoạt động có thể tìm kiếm của bạn bằng cách sử dụng ý định ACTION_SEARCH thông thường.
  • Nếu người dùng chọn một đề xuất, ý định ACTION_SEARCH sẽ được gửi đến hoạt động có thể tìm kiếm của bạn bằng văn bản đề xuất làm truy vấn.

Lớp SearchRecentSuggestionsProvider mà bạn mở rộng cho trình cung cấp nội dung sẽ tự động thực hiện công việc trong các bước trước đó, vì vậy, bạn không cần viết nhiều mã.

Tạo một trình cung cấp nội dung

Trình cung cấp nội dung bạn cần cho các cụm từ tìm kiếm gần đây được đề xuất là một cách triển khai SearchRecentSuggestionsProvider. Lớp này sẽ làm mọi việc cho bạn. Bạn chỉ cần viết một hàm khởi tạo lớp thực thi một dòng mã.

Ví dụ: sau đây là một quy trình triển khai hoàn chỉnh của trình cung cấp nội dung cho các đề xuất về cụm từ tìm kiếm gần đây:

Kotlin

class MySuggestionProvider : SearchRecentSuggestionsProvider() {
    init {
        setupSuggestions(AUTHORITY, MODE)
    }

    companion object {
        const val AUTHORITY = "com.example.MySuggestionProvider"
        const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
    }
}

Java

public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
    public final static String AUTHORITY = "com.example.MySuggestionProvider";
    public final static int MODE = DATABASE_MODE_QUERIES;

    public MySuggestionProvider() {
        setupSuggestions(AUTHORITY, MODE);
    }
}

Lệnh gọi đến setupSuggestions() sẽ truyền tên của cơ quan tìm kiếm và một chế độ cơ sở dữ liệu. Thẩm quyền tìm kiếm có thể là bất kỳ chuỗi duy nhất nào, nhưng cách tốt nhất là sử dụng tên đủ điều kiện cho trình cung cấp nội dung của bạn, chẳng hạn như tên gói theo sau là tên lớp của trình cung cấp. Ví dụ: "com.example.MySuggestionProvider".

Chế độ cơ sở dữ liệu phải có DATABASE_MODE_QUERIES và có thể có thêm DATABASE_MODE_2LINES (không bắt buộc). Chế độ này sẽ thêm một cột vào bảng đề xuất để bạn có thể cung cấp dòng văn bản thứ hai cho mỗi đề xuất. Nếu bạn muốn cung cấp 2 dòng trong mỗi đề xuất, hãy xem ví dụ sau:

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

Khai báo trình cung cấp nội dung trong tệp kê khai ứng dụng bằng cùng một chuỗi uỷ quyền được dùng trong lớp SearchRecentSuggestionsProvider và trong cấu hình có thể tìm kiếm. Ví dụ:

<application>
    <provider android:name=".MySuggestionProvider"
              android:authorities="com.example.MySuggestionProvider" />
    ...
</application>

Sửa đổi cấu hình có thể tìm kiếm

Để định cấu hình hệ thống sử dụng trình cung cấp đề xuất của bạn, hãy thêm các thuộc tính android:searchSuggestAuthorityandroid:searchSuggestSelection vào phần tử <searchable> trong tệp cấu hình có thể tìm kiếm. Ví dụ:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/app_label"
    android:hint="@string/search_hint"
    android:searchSuggestAuthority="com.example.MySuggestionProvider"
    android:searchSuggestSelection=" ?" >
</searchable>

Giá trị cho android:searchSuggestAuthority phải là tên đủ điều kiện cho trình cung cấp nội dung của bạn, khớp chính xác với quyền được dùng trong trình cung cấp nội dung, chẳng hạn như "com.example.MySuggestionProvider" trong các ví dụ trước.

Giá trị của android:searchSuggestSelection phải là một dấu chấm hỏi duy nhất, đứng trước là một dấu cách: " ?". Đây là một phần giữ chỗ cho đối số lựa chọn SQLite và được tự động thay thế bằng văn bản truy vấn do người dùng nhập.

Lưu truy vấn

Để điền sẵn bộ sưu tập các cụm từ tìm kiếm gần đây, hãy thêm từng cụm từ tìm kiếm mà hoạt động có thể tìm kiếm của bạn nhận được vào SearchRecentSuggestionsProvider. Để thực hiện việc này, hãy tạo một thực thể của SearchRecentSuggestions và gọi saveRecentQuery() mỗi khi hoạt động có thể tìm kiếm của bạn nhận được một truy vấn. Ví dụ: sau đây là cách bạn có thể lưu truy vấn trong phương thức onCreate() của hoạt động:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
                    .saveRecentQuery(query, null)
        }
    }
}

Java

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Intent intent  = getIntent();

    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
        suggestions.saveRecentQuery(query, null);
    }
}

Hàm khởi tạo SearchRecentSuggestionsProvider yêu cầu cùng một chế độ cơ sở dữ liệu và quyền được khai báo bởi trình cung cấp nội dung của bạn.

Phương thức saveRecentQuery() lấy chuỗi cụm từ tìm kiếm làm tham số đầu tiên và tuỳ chọn là chuỗi thứ hai để đưa vào làm dòng thứ hai của đề xuất hoặc giá trị rỗng. Tham số thứ hai chỉ được dùng nếu bạn bật chế độ hai dòng cho các cụm từ tìm kiếm được đề xuất bằng DATABASE_MODE_2LINES. Nếu bạn bật chế độ hai dòng, thì văn bản truy vấn sẽ khớp với dòng thứ hai khi hệ thống tìm kiếm các đề xuất phù hợp.

Xoá dữ liệu đề xuất

Để bảo vệ quyền riêng tư của người dùng, hãy luôn cung cấp cho người dùng cách xoá các đề xuất tìm kiếm gần đây. Để xoá nhật ký tìm kiếm, hãy gọi clearHistory(). Ví dụ:

Kotlin

SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
        .clearHistory()

Java

SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
        HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
suggestions.clearHistory();

Thực hiện thao tác này từ mục trình đơn "Xoá nhật ký tìm kiếm", mục tuỳ chọn ưu tiên hoặc nút mà bạn chọn. Cung cấp một hộp thoại xác nhận để xác minh rằng người dùng muốn xoá nhật ký tìm kiếm của họ.