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

روش نوشتن را امتحان کنید
Jetpack Compose ابزار رابط کاربری پیشنهادی برای اندروید است. یاد بگیرید که چگونه قابلیت جستجو را در Compose اضافه کنید.

شما می‌توانید بر اساس جستجوهای اخیر در کادر گفتگوی جستجوی اندروید یا ویجت جستجو، پیشنهادات جستجو ارائه دهید. برای مثال، اگر کاربر عبارت "توله سگ‌ها" را جستجو کند، وقتی دوباره همان عبارت را تایپ کند، آن عبارت به عنوان یک پیشنهاد ظاهر می‌شود. شکل 1 نمونه‌ای از یک کادر گفتگوی جستجو با پیشنهادات جستجوی اخیر را نشان می‌دهد.

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

اصول اولیه

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

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

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

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

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

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

  1. سیستم متن عبارت جستجو - هر چیزی که کاربر شروع به تایپ کردن می‌کند - را می‌گیرد و یک عبارت جستجو به ارائه‌دهنده محتوا که حاوی پیشنهادات شما است، ارسال می‌کند.
  2. ارائه دهنده محتوای شما یک Cursor برمی‌گرداند که به تمام پیشنهادهایی که با متن عبارت جستجو شده مطابقت دارند، اشاره می‌کند.
  3. سیستم فهرستی از پیشنهادهای ارائه شده توسط Cursor را نمایش می‌دهد.

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

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

کلاس 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> در فایل پیکربندی 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 است و به طور خودکار با متن پرس‌وجوی وارد شده توسط کاربر جایگزین می‌شود.

ذخیره کوئری‌ها

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

کاتلین

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

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