כשמוכנים להוסיף לאפליקציה פונקציונליות של חיפוש, מערכת 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>
במניפסט, מבצעים את הפעולות הבאות:
- מצהירים על הפעילות כדי לקבל את כוונת
ACTION_SEARCH
ברכיב<intent-filter>
. - מציינים את הגדרות החיפוש לשימוש ברכיב
<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
.
ביצוע חיפוש
אחרי שמצהירים על הפעילות שניתן לחפש בה במניפסט, פועלים לפי השלבים הבאים כדי לבצע חיפוש בפעילות שניתן לחפש בה:
קבלת השאילתה
כשמשתמש מבצע חיפוש מתיבת הדו-שיח או מהווידג'ט של החיפוש, המערכת מתחילה את הפעילות שניתן לחפש בה ושולחת לה intent.ACTION_SEARCH
הכוונה הזו כוללת את שאילתת החיפוש במחרוזת QUERY
extra. בודקים את הכוונה הזו כשהפעילות מתחילה ומחלצים את המחרוזת.
לדוגמה, כך אפשר לקבל את שאילתת החיפוש כשהפעילות שניתן לחפש בה מתחילה:
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. מידע על SQLite ב-Android זמין ב-sqlite.org. - אם הנתונים מאוחסנים באינטרנט, יכול להיות שביצועי החיפוש יושפעו מחיבור הנתונים של המשתמש. מומלץ להציג אינדיקטור התקדמות עד שהחיפוש יחזיר תוצאות. מידע על ממשקי API של רשתות זמין במאמר
android.net
ובמאמרProgressBar
מוסבר איך להציג אינדיקטור התקדמות.
הצגת התוצאות
לא משנה איפה הנתונים שלכם נמצאים ואיך אתם מחפשים אותם, אנחנו ממליצים להחזיר את תוצאות החיפוש לפעילות שניתן לחפש בה עם 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()
.
אפשר גם להפעיל את הפונקציונליות של 'הקלדה לחיפוש', שמפעילה את תיבת הדו-שיח של החיפוש כשהמשתמש מתחיל להקליד במקלדת. רצף הקשות מוזן בתיבת הדו-שיח של החיפוש. כדי להפעיל הקלדה לחיפוש בפעילות, צריך לקרוא ל- או ל- במהלך הפעילות שלכם בשיטה onCreate()
.setDefaultKeyMode
DEFAULT_KEYS_SEARCH_LOCAL
ההשפעה של תיבת הדו-שיח לחיפוש על מחזור החיים של הפעילות
תיבת הדו-שיח של החיפוש היא Dialog
שצפה בחלק העליון של המסך. היא לא גורמת לשינוי במצבור הפעילויות, ולכן כשמופיע תיבת הדו-שיח של החיפוש, לא מתבצעות קריאות לשיטות של מחזור החיים, כמו onPause()
. הפעילות שלכם מאבדת את מיקוד הקלט, כי מיקוד הקלט מועבר לתיבת הדו-שיח של החיפוש.
אם רוצים לקבל התראה כשתיבת הדו-שיח של החיפוש מופעלת, צריך לבטל את השיטה onSearchRequested()
. כשמערכת קוראת לשיטה הזו, זה מצביע על כך שהפעילות מאבדת את מיקוד הקלט לתיבת הדו-שיח של החיפוש, כך שאפשר לבצע כל פעולה שמתאימה לאירוע, כמו השהיית משחק. אלא אם מעבירים נתוני הקשר של החיפוש – כמו שמוסבר בקטע אחר במסמך הזה – צריך לסיים את השיטה על ידי קריאה להטמעה של מחלקת העל:
Kotlin
override fun onSearchRequested(): Boolean { pauseSomeStuff() return super.onSearchRequested() }
Java
@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"
: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 במקלדת כדי להתחיל חיפוש. אפשר להוסיף לחצן 'שליחה' על ידי קריאה ל-
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. המערכת מנהלת את רשימת ההצעות ומטפלת באירוע כשהמשתמש בוחר הצעה.
אפשר לספק שני סוגים של הצעות לחיפוש:
- הצעות לחיפוש של שאילתות מהזמן האחרון
- ההצעות האלה הן מילים שהמשתמש השתמש בהן בעבר כשאילתות חיפוש באפליקציה שלכם. מידע נוסף זמין במאמר בנושא הוספת הצעות חיפוש מותאמות אישית.
- הצעות לחיפוש בהתאמה אישית
- הצעות לחיפוש שאתם מספקים ממקור הנתונים שלכם כדי לעזור למשתמשים לבחור באופן מיידי את האיות הנכון או את הפריט שהם מחפשים. מידע נוסף זמין במאמר הוספת הצעות מותאמות אישית לחיפוש.