إضافة اقتراحات بحث مخصّص

يمكنك تقديم اقتراحات البحث استنادًا إلى طلبات البحث الأخيرة في مربّع حوار بحث Android أو أداة البحث. على سبيل المثال، إذا طلب المستخدم كلمة "جراء"، سيظهر طلب البحث كاقتراح عند كتابة طلب البحث نفسه مرة أخرى. يوضح الشكل 1 مثالاً لمربع حوار بحث يحتوي على اقتراحات طلب البحث الأخيرة.

قبل أن تبدأ، نفّذ مربع حوار البحث أو أداة بحث لإجراء عمليات البحث الأساسية في تطبيقك. ولمعرفة كيفية إجراء ذلك، يمكنك الاطّلاع على مقالة إنشاء واجهة بحث.

الأساسيّات

الشكل 1. لقطة شاشة لمربع حوار بحث يتضمن اقتراحات استعلامات حديثة.

اقتراحات طلبات البحث الأخيرة هي عمليات بحث محفوظة. عندما يختار المستخدم اقتراحًا، يتلقّى نشاطك القابل للبحث هدفًا ACTION_SEARCH مع اقتراح باعتباره طلب البحث الذي يتعامل معه نشاطك القابل للبحث.

لتقديم اقتراحات طلبات البحث الأخيرة، عليك تنفيذ ما يلي:

  • تنفيذ نشاط قابل للبحث.
  • أنشئ موفّر محتوى يوسّع نطاق SearchRecentSuggestionsProvider ويذكره في بيان التطبيق.
  • يمكنك تعديل إعدادات إمكانية البحث باستخدام معلومات حول موفّر المحتوى الذي يقدّم اقتراحات البحث.
  • يمكنك حفظ طلبات البحث إلى موفِّر المحتوى في كل مرة يتم فيها إجراء بحث.

تمامًا كما يعرض نظام Android مربع حوار البحث، فإنه يعرض اقتراحات البحث أسفل مربع الحوار أو أداة البحث. عليك تحديد المصدر الذي يسترد النظام الاقتراحات منه.

عندما يحدِّد النظام أنّ نشاطك قابل للبحث ويقدّمه اقتراحات البحث، يحدث ما يلي عندما يكتب المستخدم طلب بحث:

  1. يأخذ النظام نص طلب البحث، أيًا كان ما يبدأ المستخدم بكتابته، ويُجري طلب بحث إلى موفِّر المحتوى الذي يضم اقتراحاتك.
  2. يعرض موفِّر المحتوى Cursor الذي يشير إلى جميع الاقتراحات التي تطابق نص طلب البحث.
  3. يعرض النظام قائمة بالاقتراحات المقدَّمة من "Cursor".

بعد عرض اقتراحات طلب البحث الأخيرة، قد يحدث ما يلي:

  • إذا كتب المستخدم مفتاحًا آخر أو غيّر طلب البحث بأي طريقة، يتم تكرار الخطوات السابقة ويتم تعديل قائمة الاقتراحات.
  • وإذا نفّذ المستخدم عملية البحث، سيتم تجاهل الاقتراحات وعرض عملية البحث على نشاطك القابل للبحث باستخدام نية ACTION_SEARCH العادية.
  • إذا اختار المستخدم اقتراحًا، يتم عرض هدف ACTION_SEARCH مع نشاطك القابل للبحث باستخدام النص المقترَح كطلب بحث.

إنّ الفئة SearchRecentSuggestionsProvider التي تضيفها لموفّر المحتوى تنفّذ العمل تلقائيًا في الخطوات السابقة، لذلك لا يتوفّر سوى رمز صغير يمكن كتابته.

إنشاء موفّر محتوى

مزود المحتوى الذي تحتاج إليه للحصول على اقتراحات طلب البحث الأخيرة هو تطبيق SearchRecentSuggestionsProvider. يُجري هذا الصف كل المهام نيابةً عنك. تحتاج فقط إلى كتابة الدالة الإنشائية للفئة التي تنفذ سطرًا واحدًا من التعليمات البرمجية.

على سبيل المثال، في ما يلي مثال كامل لمزوّد محتوى لاقتراحات طلبات البحث الأخيرة:

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

يمرِّر نص الاستدعاء إلى setupSuggestions() اسم مصدر البحث ووضع قاعدة البيانات. يمكن أن يكون مرجع البحث أي سلسلة فريدة، ولكن أفضل ممارسة هي استخدام اسم مؤهل بالكامل لموفّر المحتوى، مثل اسم الحزمة متبوعًا باسم فئة مقدّم المحتوى. مثلاً، "com.example.MySuggestionProvider".

يجب أن يتضمّن وضع قاعدة البيانات DATABASE_MODE_QUERIES ويمكن أن يتضمّن اختياريًا DATABASE_MODE_2LINES، الذي يضيف عمودًا إلى جدول الاقتراحات حتى تتمكّن من تقديم سطر ثانٍ من النص مع كل اقتراح. إذا كنت تريد تقديم سطرين في كل اقتراح، فراجع المثال التالي:

Kotlin

const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES

Java

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() لنشاطك:

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

تتطلب الدالة الإنشائية SearchRecentSuggestionsProvider نفس المرجع ووضع قاعدة البيانات الذي حدده موفّر المحتوى.

تستخدم الطريقة saveRecentQuery() سلسلة طلب البحث باعتبارها المعلمة الأولى، ويمكنك اختياريًا تضمين سلسلة ثانية باعتبارها السطر الثاني من الاقتراح أو قيمة خالية. لا يتم استخدام المعلمة الثانية إلا في حال تفعيل وضع السطرين لاقتراحات البحث باستخدام DATABASE_MODE_2LINES. وفي حال تفعيل الوضع من سطرين، سيتطابق نص طلب البحث مع السطر الثاني عندما يبحث النظام عن اقتراحات مطابقة.

محو بيانات الاقتراح

لحماية خصوصية المستخدم، يجب توفير طريقة للمستخدم دائمًا لمحو الاقتراحات الأخيرة الخاصة بطلبات البحث. لمحو سجلّ طلبات البحث، عليك استدعاء clearHistory(). مثلاً:

Kotlin

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

Java

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

نفِّذ هذا الإجراء من خلال اختيار عنصر القائمة "محو سجلّ البحث" أو العنصر المفضّل أو الزر. قدِّم مربّع حوار تأكيد للتأكّد من أنّ المستخدم يريد حذف سجلّ البحث.