במסמך הזה מוסבר איך להשתמש ביוצרי תבניות Android Jetpack כדי ליצור פרוסות.
הגדרה של תבנית הפלח
פרוסות נוצרות באמצעות
ListBuilder
ListBuilder
מאפשרת להוסיף סוגים שונים של שורות שמוצגות ברשימה. הזה
מתאר כל אחד מסוגי השורות האלה ואת אופן המבנה שלהם.
פעולת SliceAction
הרכיב הבסיסי ביותר של תבנית פלח הוא
SliceAction
SliceAction
מכיל תווית יחד עם
PendingIntent
, והוא אחד מ-
הבאים:
- לחצן הסמל
- מתג ברירת המחדל
- מתג בהתאמה אישית (ניתן להזזה עם מצב הפעלה/כיבוי)
SliceAction
משמש את יוצרי התבניות שמתוארים בהמשך
. ב-SliceAction
אפשר להגדיר מצב תמונה שקובע איך
תמונה שמוצגת לפעולה:
ICON_IMAGE
: גודל קטנטן ולוח שנהSMALL_IMAGE
: גודל קטן ולא ניתן לכוונוןLARGE_IMAGE
: הגודל הגדול ביותר ושלא ניתן לבצע בו כוונון
HeaderBuilder
ברוב המקרים כדאי להגדיר כותרת לתבנית באמצעות
HeaderBuilder
כותרת יכולה לתמוך באלמנטים הבאים:
- כותרת
- כותרת משנה
- כותרת המשנה של הסיכום
- פעולה ראשית
למטה מופיעות דוגמאות להגדרות של הכותרת. שימו לב שמופיעות תיבות אפורות מיקומים פוטנציאליים של סמל ומרווח פנימי:
רינדור של כותרת עליונה בפלטפורמות שונות
כאשר יש צורך בפרוסה, משטח התצוגה קובע איך לעבד את פרוסה. שימו לב שהעיבוד עשוי להיות שונה במידה מסוימת בין פלטפורמות האירוח.
בפורמטים קטנים יותר, בדרך כלל רק הכותרת מוצגת, אם קיימת. אם המיקום ציינת סיכום לכותרת, טקסט הסיכום מוצג במקום את טקסט הכתובית.
אם לא ציינתם כותרת בתבנית, השורה הראשונה שנוספה
בדרך כלל במקום זאת מוצג ListBuilder
.
דוגמה ל-HeaderBuilder – רשימת פרוסה פשוטה עם כותרת
Kotlin
fun createSliceWithHeader(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { setAccentColor(0xff0F9D) // Specify color for tinting icons header { title = "Get a ride" subtitle = "Ride in 4 min" summary = "Work in 1 hour 45 min | Home in 12 min" } row { title = "Home" subtitle = "12 miles | 12 min | $9.00" addEndItem( IconCompat.createWithResource(context, R.drawable.ic_home), ListBuilder.ICON_IMAGE ) } }
Java
public Slice createSliceWithHeader(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setAccentColor(0xff0F9D58) // Specify color for tinting icons. .setHeader( // Create the header and add to slice. new HeaderBuilder() .setTitle("Get a ride") .setSubtitle("Ride in 4 min.") .setSummary("Work in 1 hour 45 min | Home in 12 min.") ).addRow(new RowBuilder() // Add a row. .setPrimaryAction( createActivityAction()) // A slice always needs a SliceAction. .setTitle("Home") .setSubtitle("12 miles | 12 min | $9.00") .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_home), SliceHints.ICON_IMAGE) ); // Add more rows if needed... return listBuilder.build(); }
פעולות פרוסות בכותרות
כותרות של פרוסות יכולות גם להציג SliceActions (פעולות פרוסות):
Kotlin
fun createSliceWithActionInHeader(sliceUri: Uri): Slice { // Construct our slice actions. val noteAction = SliceAction.create( takeNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_pencil), ICON_IMAGE, "Take note" ) val voiceNoteAction = SliceAction.create( voiceNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_mic), ICON_IMAGE, "Take voice note" ) val cameraNoteAction = SliceAction.create( cameraNoteIntent, IconCompat.createWithResource(context, R.drawable.ic_camera), ICON_IMAGE, "Create photo note" ) // Construct the list. return list(context, sliceUri, ListBuilder.INFINITY) { setAccentColor(0xfff4b4) // Specify color for tinting icons header { title = "Create new note" subtitle = "Easily done with this note taking app" } addAction(noteAction) addAction(voiceNoteAction) addAction(cameraNoteAction) } }
Java
public Slice createSliceWithActionInHeader(Uri sliceUri) { if (getContext() == null) { return null; } // Construct our slice actions. SliceAction noteAction = SliceAction.create(takeNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_pencil), ListBuilder.ICON_IMAGE, "Take note"); SliceAction voiceNoteAction = SliceAction.create(voiceNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_mic), ListBuilder.ICON_IMAGE, "Take voice note"); SliceAction cameraNoteAction = SliceAction.create(cameraNoteIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_camera), ListBuilder.ICON_IMAGE, "Create photo note"); // Construct the list. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setAccentColor(0xfff4b400) // Specify color for tinting icons .setHeader(new HeaderBuilder() // Construct the header. .setTitle("Create new note") .setSubtitle("Easily done with this note taking app") ) .addRow(new RowBuilder() .setTitle("Enter app") .setPrimaryAction(createActivityAction()) ) // Add the actions to the ListBuilder. .addAction(noteAction) .addAction(voiceNoteAction) .addAction(cameraNoteAction); return listBuilder.build(); }
בניית שורות
אפשר ליצור שורת תוכן באמצעות
RowBuilder
שורה
יכול לתמוך בכל אחת מהאפשרויות הבאות:
- כותרת
- כותרת משנה
- פריט התחלה: SliceAction, סמל או חותמת זמן
- פריטי סיום: SliceAction, סמל או חותמת זמן
- פעולה ראשית
אפשר לשלב את תוכן השורות בכמה דרכים, בכפוף לתנאים הבאים הגבלות:
- פריטי התחלה לא יוצגו בשורה הראשונה של פרוסה
- פריטי סיום לא יכולים להיות שילוב של
SliceAction
אובייקטים ו-Icon
אובייקטים - שורה יכולה להכיל רק חותמת זמן אחת
שורות תוכן לדוגמה מוצגות בתמונות הבאות. שימו לב שתיבות אפורות הצגת מיקומים פוטנציאליים של סמל ומרווח פנימי:
דוגמה ל-RowBuilder – מתג ל-Wi-Fi
הדוגמה הבאה מציגה שורה עם פעולה ראשית ומתג ברירת מחדל.
Kotlin
fun createActionWithActionInRow(sliceUri: Uri): Slice { // Primary action - open wifi settings. val wifiAction = SliceAction.create( wifiSettingsPendingIntent, IconCompat.createWithResource(context, R.drawable.ic_wifi), ICON_IMAGE, "Wi-Fi Settings" ) // Toggle action - toggle wifi. val toggleAction = SliceAction.createToggle( wifiTogglePendingIntent, "Toggle Wi-Fi", isConnected /* isChecked */ ) // Create the parent builder. return list(context, wifiUri, ListBuilder.INFINITY) { setAccentColor(0xff4285) // Specify color for tinting icons / controls. row { title = "Wi-Fi" primaryAction = wifiAction addEndItem(toggleAction) } } }
Java
public Slice createActionWithActionInRow(Uri sliceUri) { if (getContext() == null) { return null; } // Primary action - open wifi settings. SliceAction primaryAction = SliceAction.create(wifiSettingsPendingIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Settings" ); // Toggle action - toggle wifi. SliceAction toggleAction = SliceAction.createToggle(wifiTogglePendingIntent, "Toggle Wi-Fi", isConnected /* isChecked */); // Create the parent builder. ListBuilder listBuilder = new ListBuilder(getContext(), wifiUri, ListBuilder.INFINITY) // Specify color for tinting icons / controls. .setAccentColor(0xff4285f4) // Create and add a row. .addRow(new RowBuilder() .setTitle("Wi-Fi") .setPrimaryAction(primaryAction) .addEndItem(toggleAction)); // Build the slice. return listBuilder.build(); }
כלי לבניית רשתות
אפשר ליצור רשת של תוכן באמצעות
GridBuilder
תצוגת רשת
תומכים בסוגי התמונות הבאים:
ICON_IMAGE
: גודל קטנטן ולוח שנהSMALL_IMAGE
: גודל קטן ולא ניתן לכוונוןLARGE_IMAGE
: הגודל הגדול ביותר ושלא ניתן לבצע בו כוונון
המבנה של תא רשת הוא באמצעות
CellBuilder
א'
התא יכול לתמוך בשתי שורות טקסט ובתמונה אחת לכל היותר. אי אפשר להשאיר את השדה ריק.
דוגמאות לרשת מוצגות בתמונות הבאות:
דוגמה ב-GridRowBuilder - מסעדות בקרבת מקום
הדוגמה הבאה מציגה שורת רשת שמכילה תמונות וטקסט.
Kotlin
fun createSliceWithGridRow(sliceUri: Uri): Slice { // Create the parent builder. return list(context, sliceUri, ListBuilder.INFINITY) { header { title = "Famous restaurants" primaryAction = SliceAction.create( pendingIntent, icon, ListBuilder.ICON_IMAGE, "Famous restaurants" ) } gridRow { cell { addImage(image1, LARGE_IMAGE) addTitleText("Top Restaurant") addText("0.3 mil") contentIntent = intent1 } cell { addImage(image2, LARGE_IMAGE) addTitleText("Fast and Casual") addText("0.5 mil") contentIntent = intent2 } cell { addImage(image3, LARGE_IMAGE) addTitleText("Casual Diner") addText("0.9 mi") contentIntent = intent3 } cell { addImage(image4, LARGE_IMAGE) addTitleText("Ramen Spot") addText("1.2 mi") contentIntent = intent4 } } } }
Java
public Slice createSliceWithGridRow(Uri sliceUri) { if (getContext() == null) { return null; } // Create the parent builder. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .setHeader( // Create the header. new HeaderBuilder() .setTitle("Famous restaurants") .setPrimaryAction(SliceAction .create(pendingIntent, icon, ListBuilder.ICON_IMAGE, "Famous restaurants")) ) // Add a grid row to the list. .addGridRow(new GridRowBuilder() // Add cells to the grid row. .addCell(new CellBuilder() .addImage(image1, ListBuilder.LARGE_IMAGE) .addTitleText("Top Restaurant") .addText("0.3 mil") .setContentIntent(intent1) ).addCell(new CellBuilder() .addImage(image2, ListBuilder.LARGE_IMAGE) .addTitleText("Fast and Casual") .addText("0.5 mil") .setContentIntent(intent2) ) .addCell(new CellBuilder() .addImage(image3, ListBuilder.LARGE_IMAGE) .addTitleText("Casual Diner") .addText("0.9 mi") .setContentIntent(intent3)) .addCell(new CellBuilder() .addImage(image4, ListBuilder.LARGE_IMAGE) .addTitleText("Ramen Spot") .addText("1.2 mi") .setContentIntent(intent4)) // Every slice needs a primary action. .setPrimaryAction(createActivityAction()) ); return listBuilder.build(); }
RangeBuild
עם
RangeBuilder
אפשר ליצור שורה שמכילה סרגל התקדמות או טווח קלט, למשל
בתור פס הזזה.
דוגמאות להתקדמות ולפס הזזה מוצגות בתמונות הבאות:
דוגמה של RangeBuilder – פס הזזה
הדוגמה הבאה ממחישה איך ליצור פרוסה שמכילה נפח
את פס ההזזה באמצעות InputRangeBuilder
. כדי ליצור שורת התקדמות, משתמשים
addRange()
Kotlin
fun createSliceWithRange(sliceUri: Uri): Slice { return list(context, sliceUri, ListBuilder.INFINITY) { inputRange { title = "Ring Volume" inputAction = volumeChangedPendingIntent max = 100 value = 30 } } }
Java
public Slice createSliceWithRange(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) .addRow(new RowBuilder() // Every slice needs a row. .setTitle("Enter app") // Every slice needs a primary action. .setPrimaryAction(createActivityAction()) ) .addInputRange(new InputRangeBuilder() // Create the input row. .setTitle("Ring Volume") .setInputAction(volumeChangedPendingIntent) .setMax(100) .setValue(30) ); return listBuilder.build(); }
תוכן עיכוב
עליך להחזיר פרוסה בהקדם האפשרי מ-
SliceProvider.onBindSlice()
שיחות שצורכות זמן רב עלולות לגרום לבעיות בתצוגה, כמו הבהובים ופתאומיות
שינוי גודל.
אם יש לך תוכן פרוסה שלא ניתן לטעון במהירות, אפשר ליצור את
לפרוס את הטקסט עם placeholder ולסמן אותו ב-builder.
מתבצעת טעינה של התוכן. כאשר התוכן מוכן להצגה, התקשרו
getContentResolver().notifyChange(sliceUri, null)
באמצעות Slice URI. התוצאה תהיה קריאה נוספת אל
ב-SliceProvider.onBindSlice()
, שבו אפשר לבנות את הפלח שוב עם
תוכן.
דוגמה לתוכן עיכוב – נסיעה לעבודה
בשורה 'נסיעה לעבודה' שבהמשך, המרחק לעבודה נקבע באופן דינמי וייתכן שהיא לא תהיה זמינה באופן מיידי. הקוד לדוגמה מדגים שימוש כתובית null בתור placeholder בזמן שהתוכן נטען:
Kotlin
fun createSliceShowingLoading(sliceUri: Uri): Slice { // We’re waiting to load the time to work so indicate that on the slice by // setting the subtitle with the overloaded method and indicate true. return list(context, sliceUri, ListBuilder.INFINITY) { row { title = "Ride to work" setSubtitle(null, true) addEndItem(IconCompat.createWithResource(context, R.drawable.ic_work), ICON_IMAGE) } } }
Java
public Slice createSliceShowingLoading(Uri sliceUri) { if (getContext() == null) { return null; } // Construct the parent. ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) // Construct the row. .addRow(new RowBuilder() .setPrimaryAction(createActivityAction()) .setTitle("Ride to work") // We’re waiting to load the time to work so indicate that on the slice by // setting the subtitle with the overloaded method and indicate true. .setSubtitle(null, true) .addEndItem(IconCompat.createWithResource(getContext(), R.drawable.ic_work), ListBuilder.ICON_IMAGE) ); return listBuilder.build(); } private SliceAction createActivityAction() { return SliceAction.create( PendingIntent.getActivity( getContext(), 0, new Intent(getContext(), MainActivity.class), 0 ), IconCompat.createWithResource(getContext(), R.drawable.ic_home), ListBuilder.ICON_IMAGE, "Enter app" ); }
טיפול בגלילה מושבתת בתוך הפלח
ייתכן שמשטח שבו מוצגת תבנית הפלח לא תומך בגלילה בתוך תבנית. במקרה כזה, ייתכן שחלק מהתוכן שלכם לא יוצג.
לדוגמה, נבחן פרוסה שמציגה רשימה של רשתות Wi-Fi:
אם רשימת ה-Wi-Fi ארוכה, ואם הגלילה מושבתת, אפשר להוסיף
לחצן פרטים נוספים כדי להבטיח שהמשתמשים יוכלו לראות את כל הפריטים
חדשה. אפשר להוסיף את הלחצן באמצעות
addSeeMoreAction()
כפי שאפשר לראות בדוגמה הבאה:
Kotlin
fun seeMoreActionSlice(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { // [START_EXCLUDE] // [END_EXCLUDE] setSeeMoreAction(seeAllNetworksPendingIntent) // [START_EXCLUDE] // [END_EXCLUDE] }
Java
public Slice seeMoreActionSlice(Uri sliceUri) { if (getContext() == null) { return null; } ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY); // [START_EXCLUDE] listBuilder.addRow(new RowBuilder() .setTitle("Hello") .setPrimaryAction(createActivityAction()) ); // [END_EXCLUDE] listBuilder.setSeeMoreAction(seeAllNetworksPendingIntent); // [START_EXCLUDE] // [END_EXCLUDE] return listBuilder.build(); }
זה מוצג כפי שמוצג בתמונה הבאה:
הקשה על להצגת פרטים נוספים תשלח את seeAllNetworksPendingIntent
.
לחלופין, אם אתם רוצים להציג הודעה או שורה בהתאמה אישית, כדאי להוסיף LineBuilder:
Kotlin
fun seeMoreRowSlice(sliceUri: Uri) = list(context, sliceUri, ListBuilder.INFINITY) { // [START_EXCLUDE] // [END_EXCLUDE] seeMoreRow { title = "See all available networks" addEndItem( IconCompat.createWithResource(context, R.drawable.ic_right_caret), ICON_IMAGE ) primaryAction = SliceAction.create( seeAllNetworksPendingIntent, IconCompat.createWithResource(context, R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Networks" ) } }
Java
public Slice seeMoreRowSlice(Uri sliceUri) { if (getContext() == null) { return null; } ListBuilder listBuilder = new ListBuilder(getContext(), sliceUri, ListBuilder.INFINITY) // [START_EXCLUDE] .addRow(new RowBuilder() .setTitle("Hello") .setPrimaryAction(createActivityAction()) ) // [END_EXCLUDE] .setSeeMoreRow(new RowBuilder() .setTitle("See all available networks") .addEndItem(IconCompat .createWithResource(getContext(), R.drawable .ic_right_caret), ListBuilder.ICON_IMAGE) .setPrimaryAction(SliceAction.create(seeAllNetworksPendingIntent, IconCompat.createWithResource(getContext(), R.drawable.ic_wifi), ListBuilder.ICON_IMAGE, "Wi-Fi Networks")) ); // [START_EXCLUDE] // [END_EXCLUDE] return listBuilder.build(); }
השורה או הפעולה שנוספה באמצעות השיטה הזו מוצגות רק כאשר אחד מהתנאים הבאים עומד ב:
- מי שמציג את הפלח השבית את הגלילה בתצוגה
- אי אפשר להציג את כל השורות במרחב הזמין
שילוב תבניות
ניתן ליצור פלח דינמי עשיר על ידי שילוב של מספר סוגי שורות. עבור לדוגמה, פרוסה יכולה להכיל שורת כותרת, רשת עם תמונה אחת, רשת עם שני תאים של טקסט.
הנה פרוסה עם שורת כותרת ורשת שמכילה שלושה תאים.