תפריטים הם רכיב נפוץ בממשק משתמש בסוגים רבים של אפליקציות. שפת תרגום
לספק חוויית משתמש מוכרת ועקבית,
Menu
ממשקי API של
הצגת פעולות של משתמשים ואפשרויות אחרות בפעילויות שלכם.
המסמך הזה מראה איך ליצור את שלושת הסוגים הבסיסיים של תפריטים או מצגות של פעולות בכל הגרסאות של Android:
- תפריט האפשרויות וסרגל האפליקציות
- תפריט האפשרויות הוא האוסף הראשי של אפשרויות בתפריט עבור
פעילות. זה המקום שבו מבצעים פעולות שיש להן השפעה גלובלית
למשל 'חיפוש', "כתיבת אימייל," ו'הגדרות'.
צפייה בתפריט 'יצירה של אפשרויות' .
- תפריט הקשר ומצב פעולה לפי הקשר
- תפריט הקשר הוא תפריט צף
שמופיעה כאשר המשתמש מבצע נגיעה ללחוץ על רכיב. הוא
מציגה פעולות שמשפיעות על מסגרת ההקשר או על התוכן שנבחר.
במצב הפעולה לפי הקשר מוצגות פעולות לביצוע משפיעה על התוכן שנבחר בסרגל שבחלק העליון של המסך, ומאפשרת לבחור כמה פריטים.
ניתן לעיין בתפריט ההקשר ליצירת תפריט לפי הקשר. .
- תפריט קופץ
- תפריט קופץ מציג רשימה אנכית של פריטים שמוצמדת
מציגה את התפריט. כדאי לתת עוד הרבה פעולות
שקשורים לתוכן ספציפי או כדי לספק אפשרויות לחלק השני
של פקודה. פעולות בתפריט קופץ לא משפיעות ישירות על
את התוכן התואם – בשביל זה מיועדות פעולות לפי הקשר. במקום זאת,
התפריט הקופץ נועד לפעולות מורחבות שקשורות לאזורי תוכן
בפעילות שלכם.
פרטים נוספים זמינים בקטע יצירת תפריט קופץ.
הגדרת תפריט ב-XML
לכל סוגי התפריטים ב-Android יש פורמט XML סטנדרטי להגדרת תפריט
פריטים. במקום ליצור תפריט בקוד של הפעילות, הגדירו תפריט
את כל הפריטים ב-XML
משאב תפריט. אפשר
ולאחר מכן ננפח את משאב התפריט — נטען אותו כ-Menu
בפעילות או במקטע שלכם.
מומלץ להשתמש במשאב של תפריטים מהסיבות הבאות:
- קל יותר להציג את מבנה התפריט באופן חזותי ב-XML.
- הוא מפריד בין תוכן התפריט לבין התנהגות האפליקציה
- הוא מאפשר ליצור הגדרות תפריט חלופיות לפלטפורמה שונה גרסאות, גדלי מסך ותצורות אחרות באמצעות משאבים לאפליקציות .
כדי להגדיר תפריט, צריך ליצור קובץ XML בתוך
הספרייה res/menu/
ויוצרים את התפריט באמצעות האפשרויות הבאות
רכיבים:
<menu>
- מגדירה
Menu
, שהוא מאגר לאפשרויות בתפריט. א' הרכיב<menu>
חייב להיות הצומת של הרמה הבסיסית (root) של הקובץ, יכול להכיל ערך אחד או יותר מסוג<item>
וגם<group>
רכיבים. <item>
- יוצר
MenuItem
, שמייצג פריט יחיד בתפריט. הרכיב הזה יכול להכיל רכיב מקונן<menu>
כדי ליצור תפריט משנה. <group>
- מאגר אופציונלי בלתי נראה של
<item>
רכיבים. הוא מאפשר לחלק את האפשרויות בתפריט לקטגוריות כדי לשתף בהן מאפיינים, כמו במצב פעיל ובחשיפה. מידע נוסף זמין במאמר קטע בנושא יצירת קבוצה של תפריטים.
הנה תפריט לדוגמה בשם game_menu.xml
:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/new_game" android:icon="@drawable/ic_new_game" android:title="@string/new_game" app:showAsAction="ifRoom"/> <item android:id="@+id/help" android:icon="@drawable/ic_help" android:title="@string/help" /> </menu>
ברכיב <item>
יש תמיכה בכמה מאפיינים, שבהם אפשר להשתמש
כדי להגדיר את המראה וההתנהגות של הפריט. הפריטים בתפריט הקודם
כוללים את המאפיינים הבאים:
android:id
- מזהה משאב ייחודי לפריט, שמאפשר לאפליקציה לזהות את הפריט המשתמש בוחר בה.
android:icon
- הפניה לפריט גרפי שניתן להשתמש בו כסמל של הפריט.
android:title
- הפניה למחרוזת שתשמש ככותרת הפריט.
android:showAsAction
- המפרט שקובע מתי ואיך הפריט הזה מופיע כפעולה לביצוע בסרגל של האפליקציה.
אלה המאפיינים החשובים ביותר שבהם משתמשים, אבל יש עוד הרבה מאפיינים זמינים. מידע על כל המאפיינים הנתמכים זמין מקור מידע על התפריט התיעוד.
אפשר להוסיף תפריט משנה לפריט בכל תפריט. כדי לעשות את זה אפשר להוסיף
הרכיב <menu>
כצאצא של <item>
.
תפריטי המשנה שימושיים כשבאפליקציה יש הרבה פונקציות שאפשר לארגן
לנושאים, כמו פריטים בסרגל התפריטים של אפליקציה למחשב, כמו קובץ,
עריכה והצגה. מקרה לדוגמה:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/file" android:title="@string/file" > <!-- "file" submenu --> <menu> <item android:id="@+id/create_new" android:title="@string/create_new" /> <item android:id="@+id/open" android:title="@string/open" /> </menu> </item> </menu>
כדי להשתמש בתפריט בפעילות שלך, _inflate_ משאב התפריט, ממיר
את משאב ה-XML לאובייקט שניתן לתכנות באמצעות
MenuInflater.inflate()
בקטעים הבאים מוסבר איך להגדיל את התפריט לפי סוג התפריט.
יצירה של תפריט אפשרויות
תפריט האפשרויות, כמו זה שמוצג באיור 1, הוא המקום שבו פעולות ואפשרויות אחרות שרלוונטיות להקשר הנוכחי של הפעילות, כמו 'חיפוש', "כתיבת אימייל," ו'הגדרות'.
אפשר להצהיר על פריטים בתפריט האפשרויות מתוך
Activity
מחלקה משנית
Fragment
של מחלקה משנית. אם גם הפעילות וגם המקטעים שלך מצהירים על פריטים עבור
תפריט האפשרויות, הפריטים משולבים בממשק המשתמש. פריטי הפעילות מופיעים
הראשון, ואחריו כל המקטעים, לפי הסדר שבו
נוספים לפעילות. במידת הצורך, אפשר להזמין מחדש את האפשרויות בתפריט עם
המאפיין android:orderInCategory
בכל
<item>
שצריך להעביר.
כדי לציין את תפריט האפשרויות של פעילות מסוימת, משנים את ההגדרה
onCreateOptionsMenu()
מקטעים מספקים משלהם
onCreateOptionsMenu()
קריאה חוזרת. באמצעות השיטה הזאת אפשר להגדיל את משאב התפריט,
מוגדרים ב-XML, ב-Menu
שמצוינים ב
קריאה חוזרת. אפשר לראות זאת בדוגמה הבאה:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.game_menu, menu) return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.game_menu, menu); return true; }
אפשר גם להוסיף אפשרויות לתפריט באמצעות
add()
ולאחזר פריטים עם
findItem()
כדי לשנות את המאפיינים שלהם באמצעות ממשקי API של MenuItem
.
טיפול באירועי קליקים
כשהמשתמש בוחר פריט מתפריט האפשרויות, כולל פעולות לביצוע
בסרגל האפליקציות, המערכת קוראת לפעילות שלכם
onOptionsItemSelected()
. השיטה הזו מעבירה את MenuItem
שנבחרו. אפשר לזהות
את הפריט באמצעות התקשרות
getItemId()
,
שמחזיר את המזהה הייחודי של האפשרות בתפריט, המוגדר באמצעות הפונקציה
המאפיין android:id
במשאב התפריט או עם מספר שלם שצוין
ל-method add()
. אפשר להתאים את המזהה הזה לתפריט ידוע
פריטים כדי לבצע את הפעולה המתאימה.
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { // Handle item selection. return when (item.itemId) { R.id.new_game -> { newGame() true } R.id.help -> { showHelp() true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { // Handle item selection. switch (item.getItemId()) { case R.id.new_game: newGame(); return true; case R.id.help: showHelp(); return true; default: return super.onOptionsItemSelected(item); } }
אם האפשרות בתפריט טופלה בהצלחה, הפונקציה מחזירה את הערך true
. אם
לא מטפלים באפשרות שבתפריט, מפעילים את פונקציית העל של
onOptionsItemSelected()
פעולת ההטמעה שמוגדרת כברירת מחדל מחזירה
לא נכון.
אם הפעילות שלך כוללת מקטעים, המערכת קודם קוראת
onOptionsItemSelected()
לפעילות ואז לכל מקטע
לפי הסדר שבו המקטעים נוספו, עד שאחד המקטעים יחזיר true
או
כל המקטעים נקראים.
שינוי אפשרויות בתפריט בזמן הריצה
אחרי שהמערכת קוראת ל-onCreateOptionsMenu()
, היא שומרת
מופע של Menu
שאתם מאכלסים ולא קוראים
onCreateOptionsMenu()
שוב, אלא אם התפריט לא תקף.
עם זאת, אפשר להשתמש ב-onCreateOptionsMenu()
רק כדי ליצור את התפריט הראשוני
ולא לבצע שינויים במהלך מחזור החיים של הפעילות.
אם אתם רוצים לשנות את תפריט האפשרויות בהתאם לאירועים שמתרחשים במהלך
במחזור החיים של הפעילות, אפשר לעשות את זה
onPrepareOptionsMenu()
. השיטה הזו מעבירה את האובייקט Menu
כפי שהוא כרגע
קיים כדי שתוכל לשנות אותו, למשל על ידי הוספה, הסרה או השבתה של פריטים.
מקטעים מספקים גם
onPrepareOptionsMenu()
קריאה חוזרת.
תפריט האפשרויות נחשב תמיד פתוח כשהאפשרויות בתפריט מוצגות
בסרגל האפליקציה. כשמתרחש אירוע ורוצים לעדכן את התפריט, עליכם להתקשר
invalidateOptionsMenu()
כדי לבקש שהמערכת קוראת ל-onPrepareOptionsMenu()
.
יצירת תפריט הקשרי
תפריט לפי הקשר מציע פעולות שמשפיעות על פריט ספציפי או על הקשר מסוים
מסגרת בממשק המשתמש. אפשר לספק תפריט הקשר לכל תצוגה, אבל ברוב המקרים
לרוב בשימוש בפריטים
RecylerView
או
אוספים אחרים של צפיות שבהם המשתמש יכול לבצע פעולות ישירות בכל אוסף
שימושי.
יש שתי דרכים לספק פעולות לפי הקשר:
- בתפריט הקשר צף. תפריט מופיעה כרשימה צפה של אפשרויות בתפריט, בדומה לתיבת דו-שיח, כאשר המשתמש מבצע נגיעה להחזיק בתצוגה שלפיה יש תמיכה בהקשר מסוים תפריט המשתמשים יכולים לבצע פעולה לפי הקשר בפריט אחד בכל פעם.
- במצב הפעולה לפי הקשר. המצב הזה הוא מערכת
יישום של
ActionMode
שמציג סרגל פעולות לפי הקשר או CAB, בחלק העליון של מסך עם פעולות לביצוע שמשפיעות על הפריטים שנבחרו. במצב הזה פעיל, משתמשים יכולים לבצע פעולה על מספר פריטים בו-זמנית, אם תומך בכך.
הערה: בתפריט ההקשר אין תמיכה במקשי קיצור של פריטים ובסמלי פריטים.
יצירת תפריט הקשר צף
כדי לספק תפריט הקשר צף, מבצעים את הפעולות הבאות:
- צריך לרשום את
View
שתפריט ההקשר משויך אליו שיחותregisterForContextMenu()
ומעבירים אתView
.אם בפעילות שלכם נעשה שימוש ב-
RecyclerView
ואתם רוצים שכל אחד מהם פריט כדי לספק את אותו תפריט הקשר, רישום כל הפריטים לצורך הקשר על ידי העברתRecyclerView
אלregisterForContextMenu()
. - ליישם את
onCreateContextMenu()
ל-Activity
אוFragment
.כשהתצוגה הרשומה מקבלת מגע & אירוע hold, המערכת קוראת אמצעי התשלום
onCreateContextMenu()
. כאן מגדירים את האפשרויות בתפריט, בדרך כלל על ידי ניפוח של משאב בתפריט, כמו בדוגמה הבאה דוגמה:Kotlin
override fun onCreateContextMenu(menu: ContextMenu, v: View, menuInfo: ContextMenu.ContextMenuInfo) { super.onCreateContextMenu(menu, v, menuInfo) val inflater: MenuInflater = menuInflater inflater.inflate(R.menu.context_menu, menu) }
Java
@Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); }
MenuInflater
מאפשרת להגדיל את תפריט ההקשר מתוך משאב של תפריט. שיטת הקריאה החוזרת הפרמטרים כוללים אתView
שהמשתמש בוחר וContextMenu.ContextMenuInfo
שמספק מידע נוסף על הפריט שנבחר. אם המיקום לפעילות שלכם יש כמה תצוגות, שכל אחת מהן מספקת תפריט הקשר שונה, אפשר להשתמש בפרמטרים האלה כדי לקבוע איזה תפריט הקשר צריך לניפוח. יישום
onContextItemSelected()
, כפי שאפשר לראות בדוגמה הבאה. כשהמשתמש בוחר באחת מהאפשרויות בתפריט, הפרמטר קוראת לשיטה הזו כדי שתוכלו לבצע את הפעולה המתאימה.Kotlin
override fun onContextItemSelected(item: MenuItem): Boolean { val info = item.menuInfo as AdapterView.AdapterContextMenuInfo return when (item.itemId) { R.id.edit -> { editNote(info.id) true } R.id.delete -> { deleteNote(info.id) true } else -> super.onContextItemSelected(item) } }
Java
@Override public boolean onContextItemSelected(MenuItem item) { AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo(); switch (item.getItemId()) { case R.id.edit: editNote(info.id); return true; case R.id.delete: deleteNote(info.id); return true; default: return super.onContextItemSelected(item); } }
getItemId()
method מפעילה שאילתות על המזהה של האפשרות שנבחרה בתפריט, שמקצים לכל אחד מהם פריט בתפריט ב-XML באמצעות המאפייןandroid:id
, כפי שמוצג הגדרת תפריט ב-XML.אם האפשרות בתפריט טופלה בהצלחה, הפונקציה מחזירה את הערך
true
. אם המיקום לא מטפלים באפשרות בתפריט, מעבירים את האפשרות בתפריט למחלקה-העל יישום בפועל. אם הפעילות שלך כוללת מקטעים, הפעילות מקבלת את הקריאה החוזרת הזאת תחילה. באמצעות קריאה למחלקה-העל כשהטיפול בה לא מטופל, המערכת מעביר את האירוע לשיטת הקריאה החוזרת המתאימה בכל מקטע, אחד ב- זמן, לפי הסדר שבו התווסף כל מקטע, עדtrue
או השדהfalse
הוחזר. הטמעות ברירת מחדל עבורActivity
ו-android.app.Fragment
החזרהfalse
, לכן תמיד צריך לקרוא למחלקת העל כשלא מטפלים בה.
שימוש במצב פעולה לפי הקשר
מצב הפעולה לפי הקשר הוא הטמעת מערכת של
ActionMode
שמתמקד באינטראקציה של המשתמשים כדי להשיג ביצועים
פעולות לפי הקשר. כשמשתמש מפעיל את המצב הזה על ידי בחירה בפריט,
סרגל פעולות לפי הקשר מופיע בחלק העליון של המסך כדי להציג
פעולות שהמשתמש יכול לבצע על הפריטים שנבחרו. כשהמצב הזה מופעל,
המשתמש יכול לבחור מספר פריטים, אם האפליקציה תומכת בכך, ויכול לבטל את הבחירה
פריטים ולהמשיך לנווט בתוך הפעילות. מצב הפעולה מושבת
וסרגל הפעולות לפי ההקשר נעלם כשהמשתמש מבטל את הבחירה בכל הפריטים,
מקיש על לחצן 'הקודם', או מקיש על הפעולה סיום בצד ימין של המסך
בר.
בצפיות שמספקות פעולות לפי הקשר, אתם בדרך כלל מפעילים את אפשרות ההקשר מצב פעולה כאשר אחד משני האירועים הבאים או שניהם מתרחשים:
- המשתמש מבצע נגיעה ו את התצוגה.
- המשתמש בוחר בתיבת סימון או ברכיב דומה של ממשק המשתמש בתצוגה.
האופן שבו האפליקציה מפעילה את מצב הפעולה לפי הקשר ומגדירה את ההתנהגות של כל פעולה תלויה בעיצוב שלכם. יש שני עיצובים:
- לפעולות לפי הקשר על צפיות ספציפיות ושרירותיות.
- בשביל פעולות אצווה לפי הקשר על קבוצות של פריטים
RecyclerView
, מאפשרת למשתמש לבחור כמה פריטים וגם לבצע פעולה על כולם.
בקטעים הבאים מתוארת ההגדרה הנדרשת לכל תרחיש.
הפעלת מצב פעולה לפי הקשר בתצוגות ספציפיות
אם אתם רוצים להפעיל את מצב הפעולה לפי הקשר רק כשהמשתמש בוחר בתצוגות ספציפיות מסוימות, צריך לבצע את הפעולות הבאות:
- מטמיעים את הממשק של
ActionMode.Callback
כפי שמוצג בדוגמה הבאה. ב-methods של הקריאה החוזרת (callback), אפשר לציין את הפעולות עבור בסרגל הפעולות לפי ההקשר, להגיב לאירועי לחיצה על פעולות לביצוע טיפול באירועים אחרים במחזור החיים של מצב הפעולה.Kotlin
private val actionModeCallback = object : ActionMode.Callback { // Called when the action mode is created. startActionMode() is called. override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean { // Inflate a menu resource providing context menu items. val inflater: MenuInflater = mode.menuInflater inflater.inflate(R.menu.context_menu, menu) return true } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean { return false // Return false if nothing is done } // Called when the user selects a contextual menu item. override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean { return when (item.itemId) { R.id.menu_share -> { shareCurrentItem() mode.finish() // Action picked, so close the CAB. true } else -> false } } // Called when the user exits the action mode. override fun onDestroyActionMode(mode: ActionMode) { actionMode = null } }
Java
private ActionMode.Callback actionModeCallback = new ActionMode.Callback() { // Called when the action mode is created. startActionMode() is called. @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items. MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); return true; } // Called each time the action mode is shown. Always called after // onCreateActionMode, and might be called multiple times if the mode // is invalidated. @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; // Return false if nothing is done. } // Called when the user selects a contextual menu item. @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.menu_share: shareCurrentItem(); mode.finish(); // Action picked, so close the CAB. return true; default: return false; } } // Called when the user exits the action mode. @Override public void onDestroyActionMode(ActionMode mode) { actionMode = null; } };
הקריאות החוזרות (callback) של האירועים האלה כמעט זהות לקריאות החוזרות של תפריט האפשרויות, למעט כל אחת מהאפשרויות הוא גם מעביר את האובייקט
ActionMode
שמשויך לאירוע. ניתן להשתמש בממשקי API שלActionMode
כדי לבצע שינויים שונים CAB, למשל תיקון השם והכותרת משנה עםsetTitle()
וגםsetSubtitle()
, וזה שימושי כדי לציין כמה פריטים נבחרו.הדוגמה הקודמת מגדירה את המשתנה
actionMode
כ-null
כשמצב הפעולה מושמד. בשלב הבא, רואים האופן שבו הוא מאתחל ואיך שמירת משתנה המנוי בפעילות שלכם, או יכול להיות שימושי. - שיחת טלפון
startActionMode()
כשרוצים להציג את הסרגל, למשל כשהמשתמש מבצע מגע את התצוגה.Kotlin
someView.setOnLongClickListener { view -> // Called when the user performs a touch & hold on someView. when (actionMode) { null -> { // Start the CAB using the ActionMode.Callback defined earlier. actionMode = activity?.startActionMode(actionModeCallback) view.isSelected = true true } else -> false } }
Java
someView.setOnLongClickListener(new View.OnLongClickListener() { // Called when the user performs a touch & hold on someView. public boolean onLongClick(View view) { if (actionMode != null) { return false; } // Start the CAB using the ActionMode.Callback defined earlier. actionMode = getActivity().startActionMode(actionModeCallback); view.setSelected(true); return true; } });
כשתתבצע קריאה אל
startActionMode()
, המערכת תחזיר אתActionMode
נוצרה. אם שומרים את המשתנה הזה במשתנה מסוג 'חבר', יכול לבצע שינויים בסרגל הפעולות לפי ההקשר בתגובה לאירועים אחרים. בדוגמה הקודמת,ActionMode
משמש כדי לוודא המופע שלActionMode
לא נוצר מחדש אם הוא כבר פעיל, באמצעות בדיקה אם החבר הוא null לפני התחלת הפעולה במצב תצוגה.
יצירת תפריט קופץ
PopupMenu
הוא תפריט מודאלי שמקושר אל View
. היא מופיעה מתחת לעוגן
אם יש מקום, או מעל התצוגה, אחרת. זה שימושי
הבאים:
- הוספת תפריט אפשרויות נוספות לפעולות שקשורות אל תוכן ספציפי, כמו הכותרות של האימיילים ב-Gmail, שמוצג באיור 4.
- הצגת חלק שני של משפט פקודה, כמו לחצן שמסומן לחיצה על Add יוצרת תפריט קופץ עם אפשרויות שונות של Add. אפשרויות.
- הצגת תפריט שדומה
Spinner
שלא שומרת על בחירה מתמשכת.
אם הגדרתם את התפריט ב-XML, כך תוכלו להציג התפריט הקופץ:
- יצירת אובייקט של
PopupMenu
באמצעות ה-constructor שלו, שלוקחת האפליקציה הנוכחיתContext
וגםView
שאליו התפריט מוצמד. - שימוש ב-
MenuInflater
כדי להגדיל את משאב התפריט אובייקטMenu
הוחזר על ידיPopupMenu.getMenu()
. - התקשרות אל
PopupMenu.show()
.
לדוגמה, הנה לחצן שמציג תפריט קופץ:
<ImageButton android:id="@+id/dropdown_menu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:contentDescription="@string/descr_overflow_button" android:src="@drawable/arrow_drop_down" />
לאחר מכן, הפעילות יכולה להציג את התפריט הקופץ כך:
Kotlin
findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener { val popup = PopupMenu(this, it) val inflater: MenuInflater = popup.menuInflater inflater.inflate(R.menu.actions, popup.menu) popup.show() }
Java
findViewById(R.id.dropdown_menu).setOnClickListener(v -> { PopupMenu popup = new PopupMenu(this, v); popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu()); popup.show(); });
התפריט נסגר כשהמשתמש בוחר פריט או מקיש מחוץ לתפריט
אזור. אפשר להאזין לאירוע המחיקה באמצעות
PopupMenu.OnDismissListener
טיפול באירועי קליקים
כדי לבצע פעולה כשמשתמש בוחר אפשרות בתפריט, צריך להטמיע את הפונקציה
PopupMenu.OnMenuItemClickListener
ולרשום אותו ב-PopupMenu
באמצעות
setOnMenuItemclickListener()
.
כשמשתמש בוחר פריט, המערכת שולחת קריאה
onMenuItemClick()
קריאה חוזרת (callback) בממשק.
אפשר לראות זאת בדוגמה הבאה:
Kotlin
fun showMenu(v: View) { PopupMenu(this, v).apply { // MainActivity implements OnMenuItemClickListener. setOnMenuItemClickListener(this@MainActivity) inflate(R.menu.actions) show() } } override fun onMenuItemClick(item: MenuItem): Boolean { return when (item.itemId) { R.id.archive -> { archive(item) true } R.id.delete -> { delete(item) true } else -> false } }
Java
public void showMenu(View v) { PopupMenu popup = new PopupMenu(this, v); // This activity implements OnMenuItemClickListener. popup.setOnMenuItemClickListener(this); popup.inflate(R.menu.actions); popup.show(); } @Override public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.archive: archive(item); return true; case R.id.delete: delete(item); return true; default: return false; } }
יצירה של קבוצת תפריטים
קבוצת תפריטים היא אוסף של אפשרויות בתפריט שיש להן תכונות מסוימות. עם הקבוצה, תוכלו לבצע את הפעולות הבאות:
- הצגה או הסתרה של כל הפריטים באמצעות
setGroupVisible()
- הפעלה או השבתה של כל הפריטים באמצעות
setGroupEnabled()
- מציינים אם כל הפריטים ניתנים לבדיקה באמצעות
setGroupCheckable()
אפשר ליצור קבוצה על ידי הצבת רכיבי <item>
בתוך
לרכיב <group>
במשאב התפריט, או על ידי ציון
מזהה הקבוצה עם המאפיין
add()
.
דוגמה למשאב תפריט שכולל קבוצה:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_save" android:icon="@drawable/menu_save" android:title="@string/menu_save" /> <!-- menu group --> <group android:id="@+id/group_delete"> <item android:id="@+id/menu_archive" android:title="@string/menu_archive" /> <item android:id="@+id/menu_delete" android:title="@string/menu_delete" /> </group> </menu>
הפריטים בקבוצה מופיעים באותה רמה כמו הרמה הראשונה של הקבוצה
פריט - כל שלושת הפריטים בתפריט הם אחים. עם זאת, אפשר לשנות
את המאפיינים של שני הפריטים בקבוצה, על ידי התייחסות למזהה הקבוצה
את השיטות הקודמות. כמו כן, המערכת אף פעם לא מפרידה בין פריטים שמקובצים. עבור
לדוגמה, אם מצהירים על android:showAsAction="ifRoom"
לכל אחד
פריט, שניהם מופיעים בסרגל הפעולות או ששניהם מופיעים בפעולה
גלישה.
שימוש באפשרויות שאפשר לסמן בתפריט
תפריט יכול להיות שימושי כממשק להפעלה וכיבוי של אפשרויות, באמצעות תיבת סימון של אפשרויות נפרדות, או לחצני בחירה לקבוצות של אפשרויות בלעדיות. איור 5 מציג תפריט משנה עם פריטים שניתן לבדוק באמצעות לחצני בחירה.
אפשר להגדיר את ההתנהגות שניתנת לבדיקה לגבי אפשרויות נפרדות בתפריט באמצעות
מאפיין android:checkable
ב-<item>
או לקבוצה שלמה עם android:checkableBehavior
ברכיב <group>
. לדוגמה, כל הפריטים ב
אפשר לסמן את קבוצת התפריטים הזאת באמצעות לחצן בחירה:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <group android:checkableBehavior="single"> <item android:id="@+id/red" android:title="@string/red" /> <item android:id="@+id/blue" android:title="@string/blue" /> </group> </menu>
המאפיין android:checkableBehavior
מקבל את אחד מהבאים
הבאים:
single
- ניתן לסמן רק פריט אחד מהקבוצה, ולכן יוצג רדיו הלחצנים.
all
- אפשר לסמן את כל הפריטים, וכתוצאה מכך יופיעו תיבות סימון.
none
- אין פריטים שניתן לסמן.
אפשר להחיל מצב מסומן כברירת מחדל על פריט באמצעות
מאפיין android:checked
ברכיב <item>
ולשנות אותו בקוד באמצעות
setChecked()
.
כשבוחרים פריט שניתן לסמן, המערכת שולחת קריאה
שיטת קריאה חוזרת (callback) שנבחרה בפריט, כמו onOptionsItemSelected()
.
כאן מגדירים את מצב תיבת הסימון, כי תיבת סימון או רדיו
לא משנה את המצב באופן אוטומטי. אפשר להריץ שאילתה על המצב הנוכחי
של הפריט - כפי שהיה לפני שהמשתמש בחר אותו -
isChecked()
ואז מגדירים את המצב המסומן באמצעות setChecked()
. מוצג ב
לדוגמה:
Kotlin
override fun onOptionsItemSelected(item: MenuItem): Boolean { return when (item.itemId) { R.id.vibrate, R.id.dont_vibrate -> { item.isChecked = !item.isChecked true } else -> super.onOptionsItemSelected(item) } }
Java
@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.vibrate: case R.id.dont_vibrate: if (item.isChecked()) item.setChecked(false); else item.setChecked(true); return true; default: return super.onOptionsItemSelected(item); } }
אם לא תגדירו את המצב המסומן בדרך הזו, יופיע המצב הגלוי תיבת הסימון או לחצן הבחירה לא ישתנו כשהמשתמש בוחר בהם. אחרי שעושים להגדיר את המצב, הפעילות שומרת את המצב המסומן של הפריט, כך כשהמשתמש יפתח את התפריט מאוחר יותר, המצב המסומן שהגדרת הוא גלוי.
הוספת אפשרויות בתפריט על סמך כוונת רכישה
לפעמים רוצים שאפשרות בתפריט תפעיל פעילות באמצעות
Intent
,
בין אם מדובר בפעילות באפליקציה שלכם או באפליקציה אחרת. אחרי ש
יודעים מהי הכוונה שבה אתם רוצים להשתמש, ויש להם אפשרות ספציפית בתפריט
את הכוונה, אפשר להוציא לפועל את הכוונה
startActivity()
במהלך שיטת הקריאה החוזרת המתאימה לפריט שנבחר, כמו
התקשרות חזרה onOptionsItemSelected()
.
עם זאת, אם לא בטוח שהמכשיר של המשתמש מכיל אפליקציה מטפל בכוונה, ואז הוספת פריט בתפריט שמפעיל אותו יכולה להוביל פריט בתפריט שאינו מתפקד, מפני שהכוונה עשויה לא להוביל לפעילות. כדי לפתור את הבעיה, מערכת Android מאפשרת להוסיף אפשרויות תפריט באופן דינמי לתפריט בזמן מערכת Android מוצאת פעילויות במכשיר שמטפלות בכוונות שלך.
כדי להוסיף אפשרויות בתפריט על סמך פעילויות זמינות שמקבלות כוונה, צריך לבצע את הפעולות הבאות: הבאים:
- יש להגדיר כוונה באמצעות הקטגוריה
CATEGORY_ALTERNATIVE
אוCATEGORY_SELECTED_ALTERNATIVE
, או לשניהם, וכל דרישה אחרת. - שיחת טלפון
Menu.addIntentOptions()
לאחר מכן מערכת Android מחפשת אפליקציות שיכולות לבצע את הכוונה, מוסיף אותן לתפריט.
אם לא מותקנות אפליקציות שתואמות לכוונה, לא יהיה תפריט פריטים נוספו.
אפשר לראות זאת בדוגמה הבאה:
Kotlin
override fun onCreateOptionsMenu(menu: Menu): Boolean { super.onCreateOptionsMenu(menu) // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. val intent = Intent(null, dataUri).apply { addCategory(Intent.CATEGORY_ALTERNATIVE) } // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.componentName, // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null) // Array of MenuItems that correlate to specific items (none). return true }
Java
@Override public boolean onCreateOptionsMenu(Menu menu){ super.onCreateOptionsMenu(menu); // Create an Intent that describes the requirements to fulfill, to be // included in the menu. The offering app must include a category value // of Intent.CATEGORY_ALTERNATIVE. Intent intent = new Intent(null, dataUri); intent.addCategory(Intent.CATEGORY_ALTERNATIVE); // Search and populate the menu with acceptable offering apps. menu.addIntentOptions( R.id.intent_group, // Menu group to which new items are added. 0, // Unique item ID (none). 0, // Order for the items (none). this.getComponentName(), // The current activity name. null, // Specific items to place first (none). intent, // Intent created above that describes the requirements. 0, // Additional flags to control items (none). null); // Array of MenuItems that correlate to specific items (none). return true; }
לכל פעילות שנמצאה שמספקת מסנן Intent שתואם ל-Intent.
מוגדר, פריט תפריט מתווסף באמצעות הערך שבמסנן Intent
android:label
בתור הכותרת של האפשרות בתפריט וסמל האפליקציה בתור התפריט
סמל הפריט. השיטה addIntentOptions()
מחזירה את מספר
אפשרויות בתפריט נוספו.
מתן הרשאה להוספת הפעילות לתפריטים אחרים
אפשר להציע את השירותים של הפעילות שלך לאפליקציות אחרות, כדי שהאפליקציה שכלול בתפריט של משתמשים אחרים, ואפשר להפוך את התפקידים שתוארו קודם לכן.
כדי להיכלל בתפריטים אחרים של אפליקציות, צריך להגדיר מסנן Intent כרגיל.
אבל צריך לכלול את CATEGORY_ALTERNATIVE
או את
CATEGORY_SELECTED_ALTERNATIVE
, או שניהם, עבור ה-Intent
קטגוריית סינון. אפשר לראות זאת בדוגמה הבאה:
<intent-filter label="@string/resize_image"> ... <category android:name="android.intent.category.ALTERNATIVE" /> <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> ... </intent-filter>
מידע נוסף על כתיבת מסנני Intent זמין כאן כוונות וכוונות מסננים.