ایجاد واسط جستجو

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

وقتی آماده اضافه کردن عملکرد جستجو به برنامه‌تان هستید، Android به شما کمک می‌کند میانای کاربر را بااستفاده از کادر گفتگوی جستجو که در بالای پنجره فعالیت ظاهر می‌شود یا ابزاره جستجو که می‌توانید در چیدمانتان درج کنید پیاده‌سازی کنید. هم کادر گفتگوی جستجو و هم ابزاره می‌توانند پرسمان جستجوی کاربر را به فعالیت خاصی در برنامه شما ارسال کنند. به این ترتیب، کاربر می‌تواند جستجو را از هر فعالیتی که کادر گفتگوی جستجو یا ابزاره در آن دردسترس است شروع کند و سیستم فعالیت مناسب را برای انجام جستجو و ارائه نتایج آغاز می‌کند.

سایر ویژگی‌های دردسترس برای ابزاره و کادر گفتگوی جستجو عبارتند از:

  • جستجوی گفتاری
  • پیشنهادهای جستجو براساس پُرسمان‌های اخیر
  • پیشنهادهای جستجویی که با نتایج واقعی در داده‌های برنامه‌تان مطابقت دارد

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

منابع مرتبط:

اصول اولیه

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

  • کادر گفتگوی جستجو مؤلفه‌ای در واسط کاربر است که توسط سیستم Android کنترل می‌شود. وقتی کاربر آن را فعال می‌کند، کادر گفتگوی جستجو در بالای فعالیت ظاهر می‌شود.

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

  • ابزارک جستجو نمونه‌ای از SearchView است که می‌توانید در هرجایی از چیدمانتان قرار دهید. به‌طور پیش‌فرض، ابزاره جستجو مانند یک ابزاره استاندارد EditText رفتار می‌کند و هیچ کاری انجام نمی‌دهد، اما می‌توانید آن را پیکربندی کنید تا سیستم Android همه رویدادهای ورودی را مدیریت کند، پُرسمان‌ها را به فعالیت مناسب ارسال کند، و پیشنهادهای جستجو را ارائه دهد—درست مانند کادر گفتگوی جستجو.

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

  • پیکربندی جستجو
    فایل XML که برخی تنظیمات را برای چارگوش گفتگوی جستجو یا ابزاره پیکربندی می‌کند. این شامل تنظیمات ویژگی‌هایی مانند جستجوی گفتاری، پیشنهاد جستجو، و نوشتار راهنما برای چارگوش جستجو است.
  • فعالیت قابل‌جستجو
    Activity که پرسمان جستجو را دریافت می‌کند، داده‌هایتان را جستجو می‌کند، و نتایج جستجو را نمایش می‌دهد.
  • میانای جستجو، که توسط یکی از موارد زیر ارائه شده باشد:
    • کادر گفتگوی جستجو
      به‌طور پیش‌فرض، کادر گفتگوی جستجو پنهان است. وقتی کاربر روی دکمه جستجو شما تک‌ضرب می‌زند، این پیام در بالای صفحه ظاهر می‌شود وقتی onSearchRequested() را فراخوانی می‌کنید.
    • ابزاره SearchView
      بااستفاده از ابزاره جستجو می‌توانید چارگوش جستجو را در هرجایی از فعالیتتان قرار دهید، ازجمله به‌عنوان نمای کنش در نوار برنامه.

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

ایجاد پیکربندی جستجوشدنی

اولین چیزی که نیاز دارید یک فایل XML است که پیکربندی جستجو نامیده می‌شود. این فایل برخی‌از جنبه‌های واسط کاربر ابزاره یا کادر گفتگوی جستجو را پیکربندی می‌کند و نحوه رفتار ویژگی‌هایی مثل پیشنهادها و جستجوی گفتاری را تعریف می‌کند. این فایل معمولاً searchable.xml نامیده می‌شود و باید در فهرست راهنمای پروژه res/xml/ ذخیره شود.

فایل پیکربندی جستجو باید حاوی عنصر <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" >
</searchable>

مشخصه android:label تنها مشخصه الزامی است. این ویژگی به منبع رشته‌ای اشاره می‌کند که باید نام برنامه باشد. این برچسب تا زمانی که پیشنهادهای جستجو را برای «چارگوش جستجوی سریع» فعال نکنید برای کاربر قابل‌مشاهده نیست، در این مرحله برچسب در فهرست موارد «قابل‌جستجو» در تنظیمات سیستم قابل‌مشاهده است.

اگرچه الزامی نیست، توصیه می‌کنیم همیشه مشخصه android:hint را اضافه کنید، که رشته راهنمایی را در چارگوش جستجو قبل‌از اینکه کاربران پُرسمان را وارد کنند ارائه می‌دهد. این راهنمایی مهم است زیرا سرنخ‌های مهمی درباره آنچه کاربران می‌توانند جستجو کنند ارائه می‌دهد.

عنصر <searchable> چندین مشخصه دیگر را می‌پذیرد. بااین‌حال، تا زمانی که ویژگی‌هایی مانند پیشنهادهای جستجو و جستجوی گفتاری را اضافه نکنید، به اکثر مشخصه‌ها نیاز ندارید. برای اطلاعات دقیق درباره فایل پیکربندی جستجو، به سند مرجع پیکربندی جستجو مراجعه کنید.

ایجاد فعالیت جستجوشدنی

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

وقتی کاربر جستجویی را در ابزاره یا کادر گفتگوی جستجو اجرا می‌کند، سیستم فعالیت قابل‌جستجوی شما را شروع می‌کند و پُرسمان جستجو را در Intent با کنش ACTION_SEARCH به آن ارائه می‌دهد. فعالیت قابل‌جستجوی شما پرسمان را از QUERY اضافی هدف بازیابی می‌کند، سپس داده‌هایتان را جستجو می‌کند و نتایج را ارائه می‌دهد.

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

اعلام فعالیت قابل‌جستجو

اگر ازقبل ندارید، Activity ایجاد کنید که جستجوها را انجام دهد و نتایج را ارائه دهد. هنوز نیازی به پیاده‌سازی عملکرد جستجو نیست—فقط فعالیتی ایجاد کنید که بتوانید در مانیفست اعلام کنید. در داخل عنصر <activity> مانیفست، کارهای زیر را انجام دهید:

  1. فعالیت را برای پذیرش هدف ACTION_SEARCH در عنصر <intent-filter> اعلام کنید.
  2. پیکربندی جستجو را برای استفاده در عنصر <meta-data> مشخص کنید.

این موضوع در مثال زیر نشان داده شده است:

<application ... >
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>
    ...
</application>

عنصر <meta-data> باید شامل مشخصه android:name با مقدار "android.app.searchable" و مشخصه android:resource با ارجاع به فایل پیکربندی قابل‌جستجو باشد. در مثال بالا، به فایل res/xml/searchable.xml اشاره دارد.

انجام جستجو

پس‌از اعلام فعالیت قابل‌جستجو در مانیفست، این رویه را برای انجام جستجو در فعالیت قابل‌جستجو دنبال کنید:

  1. پرس‌وجو را دریافت می‌کند.
  2. جستجوی داده‌ها.
  3. نتایج را ارائه کنید.

دریافت پُرسمان

وقتی کاربر جستجویی را از ابزاره یا کادر گفتگوی جستجو اجرا می‌کند، سیستم فعالیت قابل‌جستجوی شما را شروع می‌کند و به آن هدف ACTION_SEARCH ارسال می‌کند. این هدف پرسمان جستجو را در رشته QUERY اضافی حمل می‌کند. وقتی فعالیت شروع می‌شود، این هدف را بررسی کنید و رشته را استخراج کنید. برای مثال، در اینجا نحوه دریافت پُرسمان جستجو هنگام شروع فعالیت قابل‌جستجو ارائه شده است:

کاتلین

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

    // Verify the action and get the query.
    if (Intent.ACTION_SEARCH == intent.action) {
        intent.getStringExtra(SearchManager.QUERY)?.also { query ->
            doMySearch(query)
        }
    }
}

جاوا

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

    // Get the intent, verify the action, and get the query.
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      doMySearch(query);
    }
}

رشته QUERY همیشه با قصد ACTION_SEARCH همراه است. در مثال بالا، پُرسمان بازیابی می‌شود و به روش doMySearch() محلی که عملیات جستجوی واقعی در آن انجام می‌شود ارسال می‌شود.

جستجوی داده‌ها

فرایند ذخیره و جستجوی داده‌هایتان مختص برنامه شما است. می‌توانید داده‌هایتان را به روش‌های مختلفی ذخیره و جستجو کنید و این سند نحوه انجام این کار را به شما نشان نمی‌دهد. نحوه ذخیره و جستجوی داده‌هایتان را ازنظر نیازها و قالب داده‌هایتان درنظر بگیرید. نکات زیر ممکن است برایتان مفید باشد:

  • اگر داده‌هایتان در پایگاه داده SQLite در دستگاه ذخیره شده است، انجام جستجوی کل نوشتار (بااستفاده از FTS3 به‌جای پُرسمان LIKE) می‌تواند جستجوی قوی‌تری در داده‌های نوشتاری ارائه دهد و نتایج را به‌طور قابل‌توجهی سریع‌تر تولید کند. برای اطلاعات درباره FTS3، به sqlite.org مراجعه کنید و برای اطلاعات درباره SQLite در Android، به SQLiteDatabase کلاس مراجعه کنید.
  • اگر داده‌هایتان به‌صورت آنلاین ذخیره شده باشد، ممکن است عملکرد جستجوی درک‌شده تحت‌تأثیر اتصال داده کاربر قرار گیرد. شاید بخواهید تا زمانی که جستجویتان برمی‌گردد، نشانگر پیشرفت را نمایش دهید. برای مرجع میاناهای برنامه‌سازی کاربردی شبکه، android.net و برای اطلاعات درباره نحوه نمایش نشانگر پیشرفت، ProgressBar را ببینید.

ارائه نتایج

صرف‌نظر از اینکه داده‌هایتان کجا قرار دارد و چگونه آن را جستجو می‌کنید، توصیه می‌کنیم نتایج جستجو را با Adapter به فعالیت قابل‌جستجویتان برگردانید. به‌این‌ترتیب، می‌توانید همه نتایج جستجو را در RecyclerView ارائه دهید. اگر داده‌هایتان از پُرسمان پایگاه داده SQLite می‌آید، می‌توانید نتایجتان را بااستفاده از CursorAdapter در RecyclerView اعمال کنید. اگر داده‌هایتان در قالب دیگری ارائه می‌شود، می‌توانید افزونه‌ای از BaseAdapter ایجاد کنید.

Adapter هر مورد از مجموعه داده را به شیء View متصل می‌کند. وقتی Adapter روی RecyclerView اعمال می‌شود، هر بخش از داده‌ها به‌عنوان یک نمای جداگانه در فهرست درج می‌شود. Adapter فقط یک میانای کاربری است، بنابراین پیاده‌سازی‌هایی مانند CursorAdapter—برای اتصال داده‌ها از Cursor— موردنیاز است. اگر هیچ‌کدام از پیاده‌سازی‌های موجود برای داده‌های شما کار نمی‌کند، می‌توانید پیاده‌سازی خودتان را از BaseAdapter انجام دهید.

استفاده از کادر گفتگوی جستجو

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

به‌طور پیش‌فرض، کادر گفتگوی جستجو همیشه پنهان است تا زمانی که کاربر آن را فعال کند. برنامه شما می‌تواند با فراخوانی onSearchRequested()، کادر گفتگوی جستجو را فعال کند. اما این روش تا زمانی که کادر گفتگوی جستجو را برای فعالیت فعال نکنید کار نمی‌کند.

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

برای اعلام فعالیت قابل‌جستجو برای کادر گفتگوی جستجوی یک فعالیت، یک عنصر <meta-data> را داخل عنصر <activity> مربوط به آن فعالیت اضافه کنید. عنصر <meta-data> باید شامل مشخصه android:value باشد که نام کلاس فعالیت قابل‌جستجو را مشخص می‌کند و مشخصه android:name با مقدار "android.app.default_searchable".

برای مثال، در اینجا اعلان مربوط به فعالیت قابل‌جستجو، SearchableActivity، و فعالیت دیگری، OtherActivity، که از SearchableActivity برای انجام جستجوهای اجراشده از کادر گفتگوی جستجو استفاده می‌کند، آورده شده است:

<application ... >
    <!-- This is the searchable activity; it performs searches. -->
    <activity android:name=".SearchableActivity" >
        <intent-filter>
            <action android:name="android.intent.action.SEARCH" />
        </intent-filter>
        <meta-data android:name="android.app.searchable"
                   android:resource="@xml/searchable"/>
    </activity>

    <!-- This activity enables the search dialog to initiate searches
         in the SearchableActivity. -->
    <activity android:name=".OtherActivity" ... >
        <!-- Enable the search dialog to send searches to SearchableActivity. -->
        <meta-data android:name="android.app.default_searchable"
                   android:value=".SearchableActivity" />
    </activity>
    ...
</application>

چون OtherActivity اکنون شامل عنصر <meta-data> برای اعلام اینکه از کدام فعالیت قابل‌جستجو برای جستجوها استفاده شود است، این فعالیت کادر گفتگوی جستجو را فعال می‌کند. اگرچه کاربر در این فعالیت است، روش onSearchRequested() کادر گفتگوی جستجو را فعال می‌کند. وقتی کاربر جستجو را اجرا می‌کند، سیستم SearchableActivity را شروع می‌کند و قصد ACTION_SEARCH را به آن ارائه می‌دهد.

اگر می‌خواهید هر فعالیتی در برنامه‌تان کادر گفتگوی جستجو را ارائه دهد، عنصر <meta-data> قبلی را به‌عنوان فرزند عنصر <application> به‌جای هر <activity> درج کنید. This way, every activity inherits the value, provides the search dialog, and delivers searches to the same searchable activity. اگر چند فعالیت قابل‌جستجو دارید، می‌توانید با قرار دادن یک <meta-data> متفاوت در داخل فعالیت‌های تکی، فعالیت قابل‌جستجوی پیش‌فرض را لغو کنید.

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

فراخوانی کادر گفتگوی جستجو

اگرچه برخی‌از دستگاه‌ها دکمه جستجوی اختصاصی ارائه می‌دهند، رفتار این دکمه ممکن است در دستگاه‌های مختلف متفاوت باشد و بسیاری از دستگاه‌ها اصلاً دکمه جستجو ارائه نمی‌دهند. بنابراین هنگام استفاده از کادر گفتگوی جستجو، باید دکمه جستجویی در واسط کاربرتان ارائه دهید که با فراخوانی onSearchRequested() کادر گفتگوی جستجو را فعال کند.

برای مثال، دکمه جستجویی در منوِ گزینه‌ها یا چیدمان میانای کاربر اضافه کنید که onSearchRequested() را فراخوانی کند.

همچنین می‌توانید عملکرد «تایپ برای جستجو» را فعال کنید که وقتی کاربر شروع به تایپ کردن روی صفحه‌کلید می‌کند، کادر گفتگوی جستجو را فعال می‌کند. کلیدهای فشرده‌شده در کادر گفتگوی جستجو درج می‌شود. می‌توانید با فراخوانی setDefaultKeyMode—یا DEFAULT_KEYS_SEARCH_LOCAL—درطول روش onCreate() فعالیتتان، جستجوی نوشتاری را در فعالیتتان فعال کنید.

تأثیر کادر گفتگوی جستجو بر چرخه حیات فعالیت شما

کادر گفتگوی جستجو یک Dialog است که در بالای صفحه شناور است. این کار باعث هیچ تغییری در پشته فعالیت نمی‌شود، بنابراین وقتی کادر گفتگوی جستجو ظاهر می‌شود، هیچ‌کدام از روش‌های چرخه حیات—مثل onPause()— فراخوانده نمی‌شوند. فعالیت شما تمرکز ورودی را ازدست می‌دهد، زیرا تمرکز ورودی به کادر گفتگوی جستجو داده می‌شود.

اگر می‌خواهید هنگام فعال شدن کادر گفتگوی جستجو مطلع شوید، روش onSearchRequested() را لغو کنید. وقتی سیستم این روش را فراخوانی می‌کند، نشان‌دهنده این است که فعالیت شما تمرکز ورودی را به کادر گفتگوی جستجو ازدست می‌دهد، بنابراین می‌توانید هر کاری را که برای این رویداد مناسب است انجام دهید، مثلاً بازی را موقتاً متوقف کنید. مگر اینکه داده‌های بافت جستجو را ارسال کنید (که در بخش دیگری از این سند بحث شده است)، متد را با فراخوانی پیاده‌سازی کلاس برتر پایان دهید:

کاتلین

override fun onSearchRequested(): Boolean {
    pauseSomeStuff()
    return super.onSearchRequested()
}

جاوا

@Override
public boolean onSearchRequested() {
    pauseSomeStuff();
    return super.onSearchRequested();
}

اگر کاربر با تک‌ضرب زدن روی دکمه «برگشتن» جستجو را لغو کند، کادر گفتگوی جستجو بسته می‌شود و فعالیت دوباره تمرکز ورودی را به‌دست می‌آورد. می‌توانید ثبت‌نام کنید تا وقتی کادر گفتگوی جستجو با setOnDismissListener()، setOnCancelListener()، یا هر دو بسته شد، مطلع شوید. فقط باید OnDismissListener را ثبت کنید، چون هربار که کادر گفتگوی جستجو بسته می‌شود، فراخوانی می‌شود. OnCancelListener فقط به رویدادهایی مربوط می‌شود که کاربر صریحاً از کادر گفتگوی جستجو خارج می‌شود، بنابراین هنگام اجرای جستجو فراخوانی نمی‌شود. وقتی جستجو اجرا می‌شود، کادر گفتگوی جستجو به‌طور خودکار ناپدید می‌شود.

اگر فعالیت فعلی فعالیت قابل‌جستجو نباشد، وقتی کاربر جستجویی را اجرا می‌کند، رویدادهای چرخه حیات فعالیت عادی راه‌اندازی می‌شود—فعالیت فعلی onPause() را دریافت می‌کند، همان‌طور که در مقدمه‌ای بر فعالیت‌ها شرح داده شده است. بااین‌حال، اگر فعالیت فعلی فعالیت قابل‌جستجو باشد، یکی از این دو اتفاق می‌افتد:

  • به‌طور پیش‌فرض، فعالیت قابل‌جستجو هدف ACTION_SEARCH را با فراخوانی onCreate() دریافت می‌کند، و نمونه جدیدی از فعالیت به بالای پشته فعالیت آورده می‌شود. اکنون دو نمونه از فعالیت قابل‌جستجوی شما در پشته فعالیت وجود دارد، بنابراین تک‌ضرب زدن روی دکمه «برگشت» شما را به نمونه قبلی فعالیت قابل‌جستجو برمی‌گرداند، به‌جای اینکه از فعالیت قابل‌جستجو خارج شوید.
  • اگر android:launchMode را روی "singleTop" تنظیم کنید، فعالیت قابل‌جستجو قصد ACTION_SEARCH را با تماس با onNewIntent(Intent) دریافت می‌کند، و قصد جدید ACTION_SEARCH را رد می‌کند. برای مثال، در اینجا نحوه رسیدگی به این مورد را می‌بینید که در آن حالت راه‌اندازی فعالیت قابل‌جستجو "singleTop" است:

    کاتلین

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.search)
        handleIntent(intent)
    }
    
    override fun onNewIntent(intent: Intent) {
        super.onNewIntent(intent)
        setIntent(intent)
        handleIntent(intent)
    }
    
    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                doMySearch(query)
            }
        }
    }

    جاوا

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);
        handleIntent(getIntent());
    }
    
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        handleIntent(intent);
    }
    
    private void handleIntent(Intent intent) {
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    درمقایسه با کد نمونه در بخش مربوط به انجام جستجو، اکنون همه کدها برای مدیریت قصد جستجو در روش handleIntent() قرار دارند تا هم onCreate() و هم onNewIntent() بتوانند آن را اجرا کنند.

    وقتی سیستم onNewIntent(Intent) را فراخوانی می‌کند، فعالیت بازراه‌اندازی نمی‌شود، بنابراین روش getIntent() همان قصدی را برمی‌گرداند که با onCreate() دریافت شده است. به همین دلیل است که باید setIntent(Intent) را در onNewIntent(Intent) فراخوانی کنید: تا اگر در آینده getIntent() را فراخوانی کردید، قصدی که توسط فعالیت ذخیره شده است به‌روز شود.

سناریو دوم، بااستفاده از حالت راه‌اندازی "singleTop"، معمولاً ترجیح داده می‌شود، زیرا پس‌از انجام جستجو، کاربر ممکن است جستجوهای بیشتری انجام دهد و شما نمی‌خواهید برنامه‌تان چندین نمونه از فعالیت قابل‌جستجو ایجاد کند. توصیه می‌کنیم فعالیت قابل‌جستجو را در مانیفست برنامه روی حالت راه‌اندازی "singleTop" تنظیم کنید، همان‌طور که در مثال زیر نشان داده شده است:

<activity android:name=".SearchableActivity"
          android:launchMode="singleTop" >
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data
          android:name="android.app.searchable"
          android:resource="@xml/searchable"/>
  </activity>

ارسال داده‌های بافت جستجو

در برخی موارد، می‌توانید اصلاحات لازم را در پرسمان جستجو در داخل فعالیت قابل‌جستجو برای هر جستجوی انجام‌شده اعمال کنید. بااین‌حال، اگر می‌خواهید معیارهای جستجویتان را براساس فعالیتی که کاربر ازطریق آن جستجو می‌کند پالایش کنید، می‌توانید داده‌های بیشتری را در قصدی که سیستم به فعالیت قابل‌جستجوی شما ارسال می‌کند ارائه دهید. می‌توانید داده‌های اضافی را در APP_DATA Bundle ارسال کنید که در قصد ACTION_SEARCH گنجانده شده است.

برای ارسال این نوع داده به فعالیت قابل‌جستجو، روش onSearchRequested() را برای فعالیتی که کاربر می‌تواند ازطریق آن جستجو انجام دهد لغو کنید، Bundle را با داده‌های اضافی ایجاد کنید، و startSearch() را برای فعال کردن کادر گفتگوی جستجو فراخوانی کنید. برای مثال:

کاتلین

override fun onSearchRequested(): Boolean {
    val appData = Bundle().apply {
        putBoolean(JARGON, true)
    }
    startSearch(null, false, appData, false)
    return true
}

جاوا

@Override
public boolean onSearchRequested() {
     Bundle appData = new Bundle();
     appData.putBoolean(SearchableActivity.JARGON, true);
     startSearch(null, false, appData, false);
     return true;
 }

برگرداندن مقدار true نشان می‌دهد که این رویداد فراخوانی را با موفقیت مدیریت می‌کنید و startSearch() را برای فعال کردن کادر گفتگوی جستجو فراخوانی می‌کنید. پس‌از اینکه کاربر پُرسمانی را ارسال می‌کند، این پُرسمان به‌همراه داده‌هایی که اضافه می‌کنید به فعالیت قابل‌جستجوی شما ارسال می‌شود. می‌توانید داده‌های اضافی را از APP_DATA Bundle استخراج کنید تا جستجو را پالایش کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

val jargon: Boolean = intent.getBundleExtra(SearchManager.APP_DATA)?.getBoolean(JARGON) ?: false

جاوا

Bundle appData = getIntent().getBundleExtra(SearchManager.APP_DATA);
if (appData != null) {
    boolean jargon = appData.getBoolean(SearchableActivity.JARGON);
}

استفاده از ابزارک جستجو

تصویری که نمای جستجو را در نوار بالای برنامه نشان می‌دهد

شکل ۱. SearchViewابزاره به‌عنوان نمای کنش در نوار برنامه.

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

پیکربندی ابزاره جستجو

پس‌از ایجاد پیکربندی جستجو و فعالیت قابل‌جستجو، جستجوی کمکی را برای هر SearchView با فراخوانی setSearchableInfo() و ارسال شیء SearchableInfo که نشان‌دهنده پیکربندی قابل‌جستجوی شما است فعال کنید.

می‌توانید با تماس با getSearchableInfo() در SearchManager مرجعی برای SearchableInfo دریافت کنید.

برای مثال، اگر از SearchView به‌عنوان نمای کنش در نوار برنامه استفاده می‌کنید، ابزاره را درطول onCreateOptionsMenu() فراخوانی برگشتی فعال کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    // Inflate the options menu from XML.
    val inflater = menuInflater
    inflater.inflate(R.menu.options_menu, menu)

    // Get the SearchView and set the searchable configuration.
    val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
    (menu.findItem(R.id.menu_search).actionView as SearchView).apply {
        // Assumes current activity is the searchable activity.
        setSearchableInfo(searchManager.getSearchableInfo(componentName))
        setIconifiedByDefault(false) // Don't iconify the widget. Expand it by default.
    }

    return true
}

جاوا

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the options menu from XML.
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);

    // Get the SearchView and set the searchable configuration.
    SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
    // Assumes current activity is the searchable activity.
    searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
    searchView.setIconifiedByDefault(false); // Don't iconify the widget. Expand it by default.

    return true;
}

اکنون ابزارک جستجو پیکربندی شده است و سیستم پُرسمان‌های جستجو را به فعالیت قابل‌جستجوی شما ارسال می‌کند. همچنین می‌توانید پیشنهادهای جستجو را برای ابزاره جستجو فعال کنید.

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

دیگر ویژگی‌های ابزاره جستجو

ابزاره SearchView چند ویژگی دیگر را که ممکن است بخواهید ارائه می‌دهد:

دکمه ارسال
به‌طور پیش‌فرض، دکمه‌ای برای ارسال پرسمان جستجو وجود ندارد، بنابراین کاربر باید کلید بازگشت را در صفحه‌کلید فشار دهد تا جستجو شروع شود. با فراخوانی setSubmitButtonEnabled(true) می‌توانید دکمه «ارسال» اضافه کنید.
پالایش پُرسمان برای پیشنهادهای جستجو
وقتی پیشنهادهای جستجو را فعال می‌کنید، معمولاً انتظار دارید کاربران پیشنهادی را انتخاب کنند، اما ممکن است بخواهند پُرسمان جستجوی پیشنهادی را نیز پالایش کنند. می‌توانید دکمه‌ای در کنار هر پیشنهاد اضافه کنید که با فراخوانی setQueryRefinementEnabled(true)، پیشنهاد را در چارگوش جستجو درج کند تا کاربر بتواند آن را اصلاح کند.
امکان تغییر وضعیت رؤیت‌پذیری چارگوش جستجو
به‌طور پیش‌فرض، ابزارک جستجو «نمادین» است، یعنی فقط با نماد جستجو (ذره‌بین) نشان داده می‌شود. وقتی کاربر روی نماد ضربه می‌زند، ازهم باز می‌شود تا چارگوش جستجو را نشان دهد. همان‌طور که در مثال قبلی نشان داده شده است، می‌توانید با فراخوانی setIconifiedByDefault(false)، چارگوش جستجو را به‌طور پیش‌فرض نشان دهید. همچنین می‌توانید با فراخوانی setIconified()، ظاهر ابزاره جستجو را تغییر دهید.

چند میانای برنامه‌سازی کاربردی دیگر در کلاس SearchView وجود دارد که به شما امکان می‌دهد ابزاره جستجو را سفارشی‌سازی کنید. بااین‌حال، اکثر آن‌ها فقط زمانی استفاده می‌شوند که خودتان همه ورودی‌های کاربر را مدیریت کنید، به‌جای اینکه از سیستم Android برای ارائه پرسمان‌های جستجو و نمایش پیشنهادهای جستجو استفاده کنید.

از ابزارک و کادر گفتگو استفاده کنید

اگر ابزاره جستجو را به‌عنوان نمای کنش در نوار برنامه درج کنید و آن را فعال کنید تا درصورت وجود فضا در نوار برنامه نشان داده شود (با تنظیم android:showAsAction="ifRoom")، ممکن است ابزاره جستجو به‌عنوان نمای کنش نشان داده نشود. بلکه، ممکن است گزینه منو در منوِ سرریز نشان داده شود. برای مثال، وقتی برنامه‌تان در صفحه‌نمایش کوچک‌تری اجرا می‌شود، ممکن است فضای کافی در نوار برنامه برای نمایش ابزاره جستجو به‌همراه دیگر موارد اقدام یا عناصر پیمایش وجود نداشته باشد، بنابراین گزینه منو در منوِ سرریز نمایش داده می‌شود. وقتی در منوی سرریز قرار می‌گیرد، مورد مانند یک مورد منوی معمولی عمل می‌کند و نمای کنش، یعنی ابزاره جستجو، را نمایش نمی‌دهد.

برای مدیریت این وضعیت، گزینه منویی که ابزاره جستجو را به آن پیوست می‌کنید باید وقتی کاربر آن را از منوِ سرریز انتخاب می‌کند، کادر گفتگوی جستجو را فعال کند. برای انجام این کار، onOptionsItemSelected() را پیاده‌سازی کنید تا گزینه منو «جستجو» را مدیریت کند و با فراخوانی onSearchRequested() کادر گفتگوی جستجو را باز کند.

برای کسب اطلاعات بیشتر درباره نحوه عملکرد موارد در نوار برنامه و نحوه مدیریت این وضعیت، به افزودن نوار برنامه مراجعه کنید.

افزودن جستجوی گفتاری

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

این موضوع در مثال زیر نشان داده شده است:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search_label"
    android:hint="@string/search_hint"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable>

برای فعال کردن جستجوی گفتاری، مقدار showVoiceSearchButton لازم است. مقدار دوم، launchRecognizer، مشخص می‌کند که دکمه جستجوی گفتاری باید تشخیص‌دهنده‌ای را راه‌اندازی کند که نوشتار ترانویسی‌شده را به فعالیت قابل‌جستجو برمی‌گرداند.

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

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

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

می‌توانید دو نوع پیشنهاد جستجو ارائه دهید:

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