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

تجربة طريقة "الكتابة"
‫Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي يُنصح باستخدامها على Android. تعرَّف على كيفية إضافة وظيفة البحث في "إنشاء".

يمكنك تقديم اقتراحات بحث استنادًا إلى طلبات البحث الأخيرة في مربّع حوار البحث أو أداة البحث على 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();

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