יצירת ממשק חיפוש

אפשר לנסות את הדרך של כתיבת הודעה
‫Jetpack Compose היא ערכת הכלים המומלצת לבניית ממשק משתמש ב-Android. איך מוסיפים פונקציית חיפוש במצב כתיבה

כשמוכנים להוסיף לאפליקציה פונקציונליות של חיפוש, מערכת Android עוזרת להטמיע את ממשק המשתמש באמצעות תיבת דו-שיח של חיפוש שמופיעה בחלק העליון של חלון הפעילות, או באמצעות ווידג'ט חיפוש שאפשר להוסיף לפריסה. גם תיבת הדו-שיח של החיפוש וגם הווידג'ט יכולים להעביר את שאילתת החיפוש של המשתמש לפעילות ספציפית באפליקציה. כך המשתמש יכול להתחיל חיפוש מכל פעילות שבה תיבת הדו-שיח של החיפוש או הווידג'ט זמינים, והמערכת מתחילה את הפעילות המתאימה כדי לבצע את החיפוש ולהציג את התוצאות.

תכונות נוספות שזמינות לתיבת הדו-שיח ולרכיב הווידג'ט של החיפוש:

  • חיפוש קולי
  • הצעות לחיפוש על סמך שאילתות מהזמן האחרון
  • הצעות לחיפוש שתואמות לתוצאות בפועל בנתוני האפליקציה

במאמר הזה מוסבר איך להגדיר את האפליקציה כך שתספק ממשק חיפוש שנתמך על ידי מערכת Android כדי להציג שאילתות חיפוש, באמצעות תיבת הדו-שיח של החיפוש או ווידג'ט החיפוש.

מקורות מידע שקשורים לנושא:

העקרונות הבסיסיים

לפני שמתחילים, מחליטים אם רוצים להטמיע את ממשק החיפוש באמצעות תיבת הדו-שיח לחיפוש או באמצעות הווידג'ט לחיפוש. הן מספקות את אותן תכונות חיפוש, אבל בדרכים שונות במקצת:

  • תיבת הדו-שיח של החיפוש היא רכיב בממשק המשתמש שנשלט על ידי מערכת Android. כשמשתמש מפעיל את האפשרות הזו, תיבת הדו-שיח של החיפוש מופיעה בחלק העליון של הפעילות.

    מערכת Android שולטת בכל האירועים בתיבת הדו-שיח של החיפוש. כשמשתמש שולח שאילתה, המערכת מעבירה את השאילתה לפעילות שציינתם לטיפול בחיפושים. בתיבת הדו-שיח יכולות להופיע גם הצעות לחיפוש בזמן שהמשתמש מקליד.

  • ווידג'ט החיפוש הוא מופע של SearchView שאפשר למקם בכל מקום בפריסה. כברירת מחדל, ווידג'ט החיפוש מתנהג כמו ווידג'ט רגיל ולא עושה כלום, אבל אפשר להגדיר אותו כך שמערכת Android תטפל בכל אירועי הקלט, תעביר את השאילתות לפעילות המתאימה ותספק הצעות לחיפוש – בדיוק כמו תיבת הדו-שיח של החיפוש.EditText

כשהמשתמש מבצע חיפוש מתיבת הדו-שיח של החיפוש או מווידג'ט חיפוש, המערכת יוצרת Intent ומאחסנת בו את שאילתת המשתמש. לאחר מכן המערכת מפעילה את הפעילות שהצהרתם עליה לטיפול בחיפושים – 'פעילות שאפשר לחפש בה' – ומעבירה לה את הבקשה. כדי להגדיר את האפליקציה לחיפוש מסוג כזה בעזרת AI, צריך:

  • הגדרת חיפוש
    קובץ 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. מציגים את התוצאות.

קבלת השאילתה

כשמשתמש מבצע חיפוש מתיבת הדו-שיח או מווידג'ט החיפוש, המערכת מתחילה את הפעילות שניתן לחפש בה ושולחת לה intent של ACTION_SEARCH. הכוונה הזו כוללת את שאילתת החיפוש במחרוזת QUERY. בודקים את הכוונה הזו כשהפעילות מתחילה ומחלצים את המחרוזת. לדוגמה, כך אפשר לקבל את שאילתת החיפוש כשהפעילות שניתן לחפש בה מתחילה:

Kotlin

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

Java

@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 ועל המחלקה SQLiteDatabase זמין ב-sqlite.org.
  • אם הנתונים שלכם מאוחסנים באינטרנט, יכול להיות שביצועי החיפוש יושפעו מחיבור הנתונים של המשתמש. מומלץ להציג אינדיקטור התקדמות עד שהחיפוש יחזיר תוצאות. android.net ProgressBar android.net

הצגת התוצאות

לא משנה איפה הנתונים שלכם נמצאים ואיך אתם מחפשים אותם, אנחנו ממליצים להחזיר את תוצאות החיפוש לפעילות שאפשר לחפש בה עם Adapter. כך תוכלו להציג את כל תוצאות החיפוש בRecyclerView. אם הנתונים מגיעים משאילתת מסד נתונים של SQLite, אפשר להחיל את התוצאות על RecyclerView באמצעות CursorAdapter. אם הנתונים שלכם מגיעים בפורמט אחר, אתם יכולים ליצור הרחבה של 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>. כך כל פעילות מקבלת בירושה את הערך, מספקת את תיבת הדו-שיח של החיפוש ומעבירה את החיפושים לאותה פעילות שאפשר לחפש בה. אם יש לכם כמה פעילויות שאפשר לחפש, אתם יכולים לשנות את ברירת המחדל של הפעילות שאפשר לחפש על ידי הצבת הצהרה שונה של <meta-data> בתוך פעילויות ספציפיות.

תיבת הדו-שיח של החיפוש מופעלת עכשיו עבור הפעילויות שלכם, והאפליקציה מוכנה לביצוע חיפושים.

הפעלת תיבת הדו-שיח של החיפוש

יש מכשירים שבהם יש לחצן חיפוש ייעודי, אבל אופן הפעולה של הלחצן עשוי להשתנות בין מכשירים, ובמכשירים רבים אין לחצן חיפוש בכלל. לכן, כשמשתמשים בתיבת הדו-שיח של החיפוש, צריך לספק לחצן חיפוש בממשק המשתמש שמפעיל את תיבת הדו-שיח של החיפוש על ידי קריאה ל-onSearchRequested().

לדוגמה, אפשר להוסיף לחצן חיפוש לתפריט האפשרויות או לפריסה של ממשק המשתמש שקורא ל-onSearchRequested().

אפשר גם להפעיל את הפונקציה 'הקלדה לחיפוש', שמפעילה את תיבת הדו-שיח של החיפוש כשהמשתמש מתחיל להקליד במקלדת. הקשות המקשים מוזנות לתיבת הדו-שיח של החיפוש. כדי להפעיל את התכונה 'הקלדה לחיפוש' בפעילות, צריך להפעיל את השיטה setDefaultKeyMode או DEFAULT_KEYS_SEARCH_LOCAL במהלך הפעילות של השיטה onCreate().

ההשפעה של תיבת הדו-שיח לחיפוש על מחזור החיים של הפעילות

תיבת הדו-שיח של החיפוש היא Dialog שצפה בחלק העליון של המסך. היא לא גורמת לשינוי ברשימת הפעילויות (activity stack), ולכן כשמופיע תיבת הדו-שיח של החיפוש, לא מתבצעות קריאות ל-methods של מחזור החיים, כמו onPause(). הפעילות מאבדת את מיקוד הקלט, כי מיקוד הקלט ניתן לתיבת הדו-שיח של החיפוש.

כדי לקבל התראה כשתיבת הדו-שיח של החיפוש מופעלת, צריך לבטל את השיטה onSearchRequested(). כשהמערכת קוראת לשיטה הזו, זה סימן שהפעילות מאבדת את מיקוד הקלט לתיבת הדו-שיח של החיפוש, כך שאפשר לבצע כל פעולה שמתאימה לאירוע, כמו השהיית משחק. אלא אם מעבירים נתוני הקשר של החיפוש – כמו שמוסבר בקטע אחר במסמך הזה – צריך לסיים את השיטה על ידי קריאה להטמעה של מחלקת האב:

Kotlin

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

Java

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

אם המשתמש מבטל את החיפוש על ידי הקשה על הכפתור "הקודם", תיבת הדו-שיח של החיפוש נסגרת וה-Activity מקבל מחדש את מיקוד הקלט. אפשר להירשם לקבלת התראה כשתיבת הדו-שיח של החיפוש נסגרת באמצעות setOnDismissListener(),‏ setOnCancelListener() או שניהם. צריך לרשום רק את הפונקציה OnDismissListener, כי היא מופעלת בכל פעם שתיבת הדו-שיח של החיפוש נסגרת. המאפיין OnCancelListener מתייחס רק לאירועים שבהם המשתמש יוצא במפורש מתיבת הדו-שיח של החיפוש, ולכן הוא לא מופעל כשמתבצע חיפוש. כשמבצעים את החיפוש, תיבת הדו-שיח של החיפוש נעלמת אוטומטית.

אם הפעילות הנוכחית היא לא הפעילות שאפשר לחפש, אירועי מחזור החיים הרגילים של הפעילות מופעלים כשהמשתמש מבצע חיפוש – הפעילות הנוכחית מקבלת onPause(), כפי שמתואר במאמר מבוא לפעילויות. עם זאת, אם הפעילות הנוכחית היא הפעילות שאפשר לחפש, אז אחד משני הדברים הבאים קורה:

  • כברירת מחדל, הפעילות שאפשר לחפש מקבלת את הכוונה ACTION_SEARCH עם קריאה אל onCreate(), ומופע חדש של הפעילות מועבר לראש ערימת הפעילויות. עכשיו יש שני מקרים של הפעילות שניתנת לחיפוש במקבץ הפעילויות הקודמות, ולכן לחיצה על לחצן 'הקודם' מחזירה אתכם למקרה הקודם של הפעילות שניתנת לחיפוש, ולא יוצאת מהפעילות שניתנת לחיפוש.
  • אם מגדירים את android:launchMode ל-"singleTop", הפעילות שניתן לחפש בה מקבלת את כוונת ACTION_SEARCH עם קריאה ל-onNewIntent(Intent), ומעבירה את כוונת ACTION_SEARCH החדשה. לדוגמה, כך אפשר לטפל במקרה שבו מצב ההפעלה של הפעילות שאפשר לחפש בה הוא "singleTop":

    Kotlin

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

    Java

    @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, שכלול ב-intent‏ ACTION_SEARCH.

כדי להעביר את סוג הנתונים הזה לפעילות שניתן לחפש בה, צריך לבטל את השיטה onSearchRequested() של הפעילות שממנה המשתמש יכול לבצע חיפוש, ליצור Bundle עם הנתונים הנוספים ולהתקשר אל startSearch() כדי להפעיל את תיבת הדו-שיח של החיפוש. לדוגמה:

Kotlin

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

Java

@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 כדי לדייק את החיפוש, כמו בדוגמה הבאה:

Kotlin

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

Java

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

שימוש בווידג'ט החיפוש

תמונה שרואים בה תצוגת חיפוש בסרגל העליון של האפליקציה

איור 1. SearchViewהווידג'ט כתצוגת פעולה בסרגל האפליקציות.

ווידג'ט החיפוש מספק את אותה פונקציונליות כמו תיבת הדו-שיח של החיפוש. הוא מפעיל את הפעילות המתאימה כשהמשתמש מבצע חיפוש, והוא יכול לספק הצעות לחיפוש ולבצע חיפוש קולי. אם אין לכם אפשרות להוסיף את ווידג'ט החיפוש לסרגל האפליקציות, אתם יכולים להוסיף אותו לפריסת הפעילות.

הגדרת ווידג'ט החיפוש

אחרי שיוצרים הגדרת חיפוש ופעילות שאפשר לחפש, מפעילים את החיפוש בעזרת AI לכל SearchView על ידי קריאה ל-setSearchableInfo() והעברת האובייקט SearchableInfo שמייצג את ההגדרה שאפשר לחפש.

אפשר לקבל הפניה אל SearchableInfo על ידי קריאה ל-getSearchableInfo() ב-SearchManager.

לדוגמה, אם משתמשים ב-SearchView כתצוגת פעולה בסרגל האפליקציות, צריך להפעיל את הווידג'ט במהלך הקריאה החוזרת onCreateOptionsMenu(), כמו בדוגמה הבאה:

Kotlin

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
}

Java

@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 כולל כמה תכונות נוספות שאולי תרצו להשתמש בהן:

כפתור שליחה
כברירת מחדל, אין לחצן לשליחת שאילתת חיפוש, ולכן המשתמש צריך ללחוץ על מקש Return במקלדת כדי להתחיל חיפוש. You can add a "submit" button by calling setSubmitButtonEnabled(true).
מיקוד השאילתה להצעות לחיפוש
כשמפעילים את ההצעות לחיפוש, בדרך כלל מצפים שהמשתמשים יבחרו הצעה, אבל יכול להיות שהם ירצו גם לשנות את שאילתת החיפוש המוצעת. אתם יכולים להוסיף לחצן לצד כל הצעה, שיכניס את ההצעה לתיבת החיפוש כדי שהמשתמש יוכל לשפר אותה. כדי לעשות זאת, צריך להפעיל את setQueryRefinementEnabled(true).
אפשרות להצגה או להסתרה של תיבת החיפוש
כברירת מחדל, ווידג'ט החיפוש הוא 'סמלי', כלומר הוא מיוצג רק על ידי סמל חיפוש – זכוכית מגדלת. הוא מתרחב כדי להציג את תיבת החיפוש כשהמשתמש מקיש על הסמל. כפי שמוצג בדוגמה הקודמת, אפשר להציג את תיבת החיפוש כברירת מחדל על ידי קריאה ל-setIconifiedByDefault(false). אפשר גם להחליף את המראה של ווידג'ט החיפוש על ידי קריאה ל- setIconified().

יש עוד כמה ממשקי API במחלקה 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. המערכת מנהלת את רשימת ההצעות ומטפלת באירוע כשהמשתמש בוחר הצעה.

אפשר לספק שני סוגים של הצעות לחיפוש:

הצעות לחיפוש של שאילתות מהזמן האחרון
ההצעות האלה הן מילים שהמשתמש השתמש בהן בעבר כשאלות חיפוש באפליקציה שלכם. מידע נוסף זמין במאמר בנושא הוספה של הצעות חיפוש מותאמות אישית.
הצעות לחיפוש בהתאמה אישית
הצעות לחיפוש שאתם מספקים ממקור הנתונים שלכם כדי לעזור למשתמשים לבחור מיד את האיות הנכון או את הפריט שהם מחפשים. מידע נוסף זמין במאמר הוספת הצעות לחיפוש בהתאמה אישית.