افزودن پیشنهادهای جستجوی سفارشی

امتحان کردن روش Compose
Jetpack Compose جعبه‌ابزار واسط کاربر توصیه‌شده برای Android است. با نحوه افزودن عملکرد جستجو در Compose آشنا شوید.

می‌توانید پیشنهادهای جستجو را براساس پرسمان‌های جستجوی اخیر در کادر گفتگوی جستجوی Android یا ابزاره جستجو ارائه دهید. برای مثال، اگر کاربری «توله سگ» را پُرسمان کند، وقتی دوباره همان پُرسمان را تایپ می‌کند، پُرسمان به‌عنوان پیشنهاد نشان داده می‌شود. شکل ۱ نمونه‌ای از کادر گفتگوی جستجو با پیشنهادهای پُرسمان اخیر را نشان می‌دهد.

قبل‌از شروع، کادر گفتگوی جستجو یا ابزاره جستجو را برای جستجوهای پایه در برنامه‌تان پیاده‌سازی کنید. برای آشنایی با نحوه انجام این کار، ایجاد میانای جستجو را ببینید.

اصول اولیه

شکل ۱. نماگرفت کادر گفتگوی جستجو با پیشنهادهای پُرسمان اخیر.

پیشنهادهای پُرسمان اخیر جستجوهای ذخیره‌شده هستند. وقتی کاربر پیشنهادی را انتخاب می‌کند، فعالیت قابل‌جستجوی شما ACTION_SEARCH قصدی با پیشنهاد به‌عنوان پرسمان جستجو دریافت می‌کند که فعالیت قابل‌جستجوی شما ازقبل آن را مدیریت می‌کند.

برای ارائه پیشنهادهای پُرسمان‌های اخیر، باید:

  • فعالیت قابل‌جستجویی را پیاده‌سازی کنید.
  • ارائه‌دهنده محتوایی ایجاد کنید که SearchRecentSuggestionsProvider را گسترش دهد و آن را در مانیفست برنامه‌تان اعلام کنید.
  • پیکربندی قابل‌جستجو را با اطلاعاتی درباره ارائه‌دهنده محتوایی که پیشنهادهای جستجو را ارائه می‌دهد اصلاح کنید.
  • هر بار که جستجویی اجرا می‌شود، پُرسمان‌ها را در ارائه‌دهنده محتوایتان ذخیره کنید.

همان‌طور که سیستم Android کادر گفتگوی جستجو را نمایش می‌دهد، پیشنهادهای جستجو را نیز در زیر کادر گفتگو یا ابزاره جستجو نمایش می‌دهد. شما منبعی را که سیستم پیشنهادها را از آن بازیابی می‌کند ارائه می‌دهید.

وقتی سیستم تشخیص می‌دهد که فعالیت شما قابل‌جستجو است و پیشنهادهای جستجو ارائه می‌دهد، هنگامی که کاربر پُرسمانی را تایپ می‌کند، موارد زیر اتفاق می‌افتد:

  1. سیستم نوشتار پُرسمان جستجو را (هرآنچه کاربر شروع به تایپ کردن می‌کند) می‌گیرد و پُرسمانی را برای ارائه‌دهنده محتوایی که حاوی پیشنهادهای شما است اجرا می‌کند.
  2. ارائه‌دهنده محتوای شما Cursor را برمی‌گرداند که به همه پیشنهادهای منطبق با نوشتار پرسمان جستجو اشاره می‌کند.
  3. سیستم فهرست پیشنهادهای ارائه‌شده توسط Cursor را نمایش می‌دهد.

وقتی پیشنهادهای پُرسمان اخیر نمایش داده می‌شود، ممکن است موارد زیر اتفاق بیفتد:

  • اگر کاربر کلید دیگری را تایپ کند یا پُرسمان را به هر نحوی تغییر دهد، مراحل قبلی تکرار می‌شود و فهرست پیشنهاد به‌روز می‌شود.
  • اگر کاربر جستجو را اجرا کند، پیشنهادها نادیده گرفته می‌شود و جستجو بااستفاده از هدف ACTION_SEARCH معمولی به فعالیت قابل‌جستجوی شما ارسال می‌شود.
  • اگر کاربر پیشنهادی را انتخاب کند، یک هدف ACTION_SEARCH بااستفاده از نوشتار پیشنهادی به‌عنوان پُرسمان به فعالیت قابل‌جستجوی شما ارسال می‌شود.

کلاس SearchRecentSuggestionsProvider که برای ارائه‌دهنده محتوایتان گسترش می‌دهید به‌طور خودکار کار را در مراحل قبلی انجام می‌دهد، بنابراین کد کمی برای نوشتن وجود دارد.

ایجاد ارائه‌دهنده محتوا

ارائه‌دهنده محتوایی که برای پیشنهادهای پرسمان اخیر نیاز دارید، پیاده‌سازی SearchRecentSuggestionsProvider است. این کلاس همه کارها را برای شما انجام می‌دهد. فقط باید سازنده کلاسی بنویسید که یک خط کد را اجرا کند.

برای مثال، در اینجا پیاده‌سازی کامل ارائه‌دهنده محتوا برای پیشنهادهای پُرسمان اخیر آورده شده است:

کاتلین

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

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

جاوا

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

فراخوانی setupSuggestions() نام مرجع جستجو و حالت پایگاه داده را ارسال می‌کند. مرجع جستجو می‌تواند هر رشته منحصربه‌فردی باشد، اما بهترین روش استفاده از نام کاملاً واجدشرایط برای ارائه‌دهنده محتوا است، مانند نام بسته و به‌دنبال آن نام کلاس ارائه‌دهنده. برای مثال، "com.example.MySuggestionProvider".

حالت پایگاه داده باید شامل DATABASE_MODE_QUERIES باشد و می‌تواند به‌صورت اختیاری شامل DATABASE_MODE_2LINES باشد که ستونی به جدول پیشنهادها اضافه می‌کند تا بتوانید خط دوم نوشتار را با هر پیشنهاد ارائه دهید. اگر می‌خواهید در هر پیشنهاد دو خط ارائه دهید، مثال زیر را ببینید:

کاتلین

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

جاوا

public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;

ارائه‌دهنده محتوا را در مانیفست برنامه با همان رشته مرجع استفاده‌شده در کلاس SearchRecentSuggestionsProvider و در پیکربندی قابل‌جستجو اعلام کنید. برای مثال:

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

اصلاح پیکربندی قابل‌جستجو

برای پیکربندی سیستم جهت استفاده از ارائه‌دهنده پیشنهادهایتان، مشخصه‌های android:searchSuggestAuthority و android:searchSuggestSelection را به عنصر <searchable> در فایل پیکربندی قابل‌جستجویتان اضافه کنید. برای مثال:

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

مقدار android:searchSuggestAuthority باید نام کاملاً واجدشرایطی برای ارائه‌دهنده محتوای شما باشد که دقیقاً با مرجع استفاده‌شده در ارائه‌دهنده محتوا مطابقت داشته باشد، مانند "com.example.MySuggestionProvider" در مثال‌های قبلی.

مقدار android:searchSuggestSelection باید یک علامت سؤال تکی باشد که قبل‌از آن فاصله قرار دارد: " ?". این جای‌بانی برای متغیر مستقل انتخاب SQLite است و به‌طور خودکار با نوشتار پُرسمان واردشده توسط کاربر جایگزین می‌شود.

ذخیره کردن پُرسمان‌ها

برای پر کردن مجموعه پُرسمان‌های اخیرتان، هر پُرسمان دریافتی از فعالیت قابل‌جستجویتان را به SearchRecentSuggestionsProvider خود اضافه کنید. برای انجام این کار، نمونه‌ای از SearchRecentSuggestions ایجاد کنید و هربار که فعالیت قابل‌جستجوی شما پُرسمانی دریافت می‌کند، saveRecentQuery() را فراخوانی کنید. برای مثال، در اینجا نحوه ذخیره کردن پُرسمان درطول روش onCreate() فعالیتتان آورده شده است:

کاتلین

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

جاوا

@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);
    }
}

سازنده SearchRecentSuggestionsProvider به همان مرجع و حالت پایگاه داده‌ای نیاز دارد که توسط ارائه‌دهنده محتوای شما اعلام شده است.

روش saveRecentQuery() رشته پرسمان جستجو را به‌عنوان پارامتر اول و به‌صورت اختیاری، رشته دوم را برای گنجاندن به‌عنوان خط دوم پیشنهاد یا null می‌گیرد. پارامتر دوم فقط درصورتی استفاده می‌شود که حالت دوخطی را برای پیشنهادهای جستجو با DATABASE_MODE_2LINES فعال کنید. اگر حالت دوخطی را فعال کنید، وقتی سیستم به‌دنبال پیشنهادهای منطبق می‌گردد، نوشتار پُرسمان با خط دوم مطابقت داده می‌شود.

پاک کردن داده‌های پیشنهاد

برای محافظت از حریم خصوصی کاربر، همیشه راهی برای پاک کردن پیشنهادهای پُرسمان اخیر برای کاربر فراهم کنید. برای پاک کردن سابقه پُرسمان، clearHistory() را فراخوانی کنید. برای مثال:

کاتلین

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

جاوا

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

این کار را ازطریق گزینه منو، گزینه اولویت، یا دکمه «پاک کردن سابقه جستجو» انجام دهید. کادر گفتگوی تأییدی ارائه دهید تا تأیید شود که کاربر می‌خواهد سابقه جستجویش را حذف کند.