יצירת ווידג'ט פשוט

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

דוגמה לווידג'ט מוזיקה
איור 1. דוגמה לווידג'ט מוזיקה.

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

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

רכיבי הווידג'ט

כדי ליצור ווידג'ט, צריך את הרכיבים הבסיסיים הבאים:

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

איור 2 מראה איך הרכיבים האלה משתלבים בעיבוד הכולל של הווידג'טים של האפליקציה .

תהליך העיבוד של ווידג'ט האפליקציה
איור 2. תהליך העיבוד של הווידג'ט של האפליקציה.

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

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

הצהרה על קובץ ה-XML של AppWidgetProviderInfo

האובייקט AppWidgetProviderInfo מגדיר את התכונות החיוניות של ווידג'ט. מגדירים את האובייקט AppWidgetProviderInfo בקובץ משאבים מסוג XML באמצעות <appwidget-provider> ולשמור אותו בתיקייה של הפרויקט res/xml/.

אפשר לראות זאת בדוגמה הבאה:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:targetCellWidth="1"
    android:targetCellHeight="1"
    android:maxResizeWidth="250dp"
    android:maxResizeHeight="120dp"
    android:updatePeriodMillis="86400000"
    android:description="@string/example_appwidget_description"
    android:previewLayout="@layout/example_appwidget_preview"
    android:initialLayout="@layout/example_loading_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigurationActivity"
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen"
    android:widgetFeatures="reconfigurable|configuration_optional">
</appwidget-provider>

מאפייני המידה של הווידג'ט

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

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

בטבלה הבאה מתוארים המאפיינים של <appwidget-provider> שקשורים עד לגודל הווידג'ט:

מאפיינים ותיאור
targetCellWidth והקבוצה targetCellHeight (Android 12), minWidth וminHeight
  • החל מ-Android 12, targetCellWidth ו-targetCellHeight מציינים את גודל ברירת המחדל של הווידג'ט מבחינת הרשת תאים. ב-Android 11 המערכת מתעלמת מהמאפיינים האלה נמוכה יותר, ואפשר להתעלם ממנו אם מסך הבית לא לתמוך בפריסה שמבוססת על רשת.
  • minWidth וגם מאפייני minHeight מציינים את גודל ברירת המחדל של הווידג'ט ב-dp. אם הערכים של הרוחב או הגובה המינימלי של הווידג'ט לא תואמים את גודל התאים, והערכים יעוגלו כלפי מעלה גודל התא הקרוב ביותר.
מומלץ לציין את שתי הקבוצות של מאפיינים - targetCellWidth וגם targetCellHeight, minWidth וגם minHeight – כדי שאפשר יהיה לחזור להשתמש באפליקציה minWidth ו-minHeight אם המכשיר של המשתמש לא תומך ב-targetCellWidth targetCellHeight. אם האפשרות נתמכת, הפרמטר מאפיינים של targetCellWidth ו-targetCellHeight מקבלים עדיפות על פני minWidth ו-minHeight .
minResizeWidth והקבוצה minResizeHeight צריך לציין את הגודל המינימלי המוחלט של הווידג'ט. הערכים האלה מציינים את הגודל שבו הווידג'ט לא קריא או לא שמיש מסיבה אחרת. באמצעות הם מאפשרים למשתמש לשנות את גודל הווידג'ט לגודל קטן יותר מגודל ברירת המחדל של הווידג'ט. המאפיין minResizeWidth הוא המערכת מתעלמת ממנו אם הוא גדול מ-minWidth או אם הוא אופקי שינוי הגודל לא מופעל. צפייה resizeMode באופן דומה, המערכת תתעלם מהמאפיין minResizeHeight אם הוא גדול מ- minHeight או אם האפשרות לשינוי גודל אנכי לא מופעלת.
maxResizeWidth והקבוצה maxResizeHeight מציינים את הגודל המקסימלי המומלץ לווידג'ט. אם הערכים לא כפולה של תאי הרשת, הם מעוגלים כלפי מעלה גודל התא. המערכת מתעלמת מהמאפיין maxResizeWidth אם קטן מ-minWidth או אם הגודל האופקי לא מוצג מופעל. פרטים נוספים זמינים בכתובת resizeMode. באופן דומה, המערכת תתעלם מהמאפיין maxResizeHeight אם הוא גדול מ-minHeight, או אם האפשרות לשינוי גודל אנכי לא מופעלת. התכונה הושקה ב-Android 12.
resizeMode מציינת את הכללים שלפיהם ניתן לשנות את הגודל של ווידג'ט. אפשר להשתמש כדי לשנות את גודל הווידג'טים של מסך הבית במאוזן, במאונך, או על שני הצירים. משתמשים במגע & להחזיק ווידג'ט כדי להציג את נקודות האחיזה לשינוי הגודל שלו, ולאחר מכן לגרור את נקודות האחיזה האופקיות או האנכיות כדי לשנות את הגודל שלהן פריסת רשת. ערכי המאפיין resizeMode כוללים horizontal, vertical וגם none. שפת תרגום להצהיר על ווידג'ט שניתן לשנות את גודלו לרוחב ואנכי, horizontal|vertical

דוגמה

כדי להמחיש איך המאפיינים בטבלה הקודמת משפיעים על גודל הווידג'טים, מניחים את המפרטים הבאים:

  • תא רשת הוא ברוחב של 30dp וגובה של 50dp.
  • מפרט המאפיינים הבא סופק:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="80dp"
    android:minHeight="80dp"
    android:targetCellWidth="2"
    android:targetCellHeight="2"
    android:minResizeWidth="40dp"
    android:minResizeHeight="40dp"
    android:maxResizeWidth="120dp"
    android:maxResizeHeight="120dp"
    android:resizeMode="horizontal|vertical" />

החל מ-Android 12:

שימוש במאפיינים targetCellWidth ו-targetCellHeight כברירת המחדל הגודל של הווידג'ט.

גודל הווידג'ט הוא 2x2 כברירת מחדל. ניתן להקטין את גודל הווידג'ט ל-2x1 או עד 4x3.

Android 11 ומטה:

אפשר להשתמש במאפיינים minWidth ו-minHeight כדי לחשב את גודל ברירת המחדל של לווידג'ט.

רוחב ברירת המחדל = Math.ceil(80 / 30) = 3

גובה ברירת המחדל = Math.ceil(80 / 50) = 2

גודל הווידג'ט הוא 3x2 כברירת מחדל. ניתן להקטין את גודל הווידג'ט ל-2x1 או עד למסך מלא.

מאפייני ווידג'ט נוספים

בטבלה הבאה מתוארים המאפיינים של <appwidget-provider> שקשורים לתכונות שאינן גודל הווידג'ט.

מאפיינים ותיאור
updatePeriodMillis מגדירה את התדירות שבה ה-framework של הווידג'ט מבקש עדכון AppWidgetProvider באמצעות onUpdate() שיטת קריאה חוזרת. לא בטוח שהעדכון יתבצע בדיוק בתאריך עם הערך הזה. מומלץ לעדכן בתדירות נמוכה ככל האפשר אפשרי - לא יותר מפעם בשעה - כדי לחסוך בצריכת הסוללה. כדי לקבל את רשימת השיקולים המלאה שיש לבחור תקופת עדכון מתאימה, לראות אופטימיזציות לעדכון ווידג'ט .
initialLayout מצביע על משאב הפריסה שמגדיר את פריסת הווידג'ט.
configure מגדיר את הפעילות שמופעלת כשהמשתמש מוסיף את הווידג'ט, ולאפשר להם להגדיר מאפייני ווידג'ט. צפייה המשתמשים יכולים להגדיר ווידג'טים. החל מ-Android 12, האפליקציה יכולה לדלג על השלב הראשוני הגדרה אישית. אפשר לעיין בקטע שימוש הגדרות ברירת המחדל של הווידג'ט לפרטים נוספים.
description מציינת את התיאור שיוצג בכלי לבחירת ווידג'טים לווידג'ט הזה. התכונה הושקה ב-Android 12.
previewLayout (Android 12) ו-previewImage (Android 11 ומטה)
  • החל מ-Android 12, המאפיין previewLayout מציין תצוגה מקדימה ניתנת להתאמה, מספקים כפריסת XML שמוגדרת לגודל ברירת המחדל של הווידג'ט. במצב אידיאלי, ה-XML של הפריסה שמצוין במאפיין הזה זהה ל-XML פריסה כמו עם ערכי ברירת מחדל מציאותיים.
  • ב-Android 11 ומטה, previewImage מציין תצוגה מקדימה של מראה הווידג'ט לאחר מוגדרת, שהמשתמש רואה כשהוא בוחר את הווידג'ט של האפליקציה. אחרת סופק, המשתמש יראה במקום זאת את סמל מרכז האפליקציות של האפליקציה שלך. הזה השדה תואם למאפיין android:previewImage ב- את הרכיב <receiver> קובץ AndroidManifest.xml.
הערה: מומלץ לציין גם את השדות previewImage ו-previewLayout כדי לאפשר שימוש חוזר באפליקציה לשימוש ב-previewImage אם המכשיר של המשתמש לא תומך previewLayout פרטים נוספים זמינים במאמר תאימות לאחור עם יכולת התאמה תצוגות מקדימות של הווידג'טים.
autoAdvanceViewId מציין את מזהה התצוגה המפורטת של תצוגת המשנה של הווידג'ט שמתקדמת באופן אוטומטי באמצעות המארח של הווידג'ט.
widgetCategory מצהירה אם ניתן להציג את הווידג'ט במסך הבית (home_screen), מסך הנעילה (keyguard) או ובשניהם. עבור Android 5.0 ומעלה, רק home_screen תקף.
widgetFeatures מצהירה על תכונות שנתמכות בווידג'ט. לדוגמה, אם רוצים לווידג'ט להשתמש בהגדרות ברירת המחדל שלו כשמשתמש מוסיף אותו, מציינים גם את configuration_optional וגם reconfigurable סימונים אוטומטיים. ההגדרה הזו עוקפת את ההפעלה של פעילות ההגדרות האישיות אחרי שמשתמש מוסיף את הווידג'ט. המשתמש עדיין יכול להגדיר מחדש את הווידג'ט לאחר מכן.

שימוש במחלקה AppWidgetProvider כדי לטפל בשידורי ווידג'טים

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

הצהרה על ווידג'ט במניפסט

קודם צריך להצהיר על הכיתה AppWidgetProvider ב-AndroidManifest.xml של האפליקציה כפי שמוצג בדוגמה הבאה:

<receiver android:name="ExampleAppWidgetProvider"
                 android:exported="false">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>
    <meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>

לרכיב <receiver> נדרש המאפיין android:name, שמציין AppWidgetProvider שמשמש את הווידג'ט. אסור לייצא את הרכיב אלא אם נדרש תהליך נפרד לשידור אל AppWidgetProvider, בדרך כלל זה לא המצב.

הרכיב <intent-filter> חייב לכלול רכיב <action> עם מאפיין android:name. המאפיין הזה מציין שהמאפיין AppWidgetProvider מקבל/ת את ACTION_APPWIDGET_UPDATE שידור. זהו השידור היחיד שעליך להצהיר עליו במפורש. AppWidgetManager שולח באופן אוטומטי את כל שידורי הווידג'ט האחרים ל-AppWidgetProvider בתור הנחוצים.

הרכיב <meta-data> מציין את המשאב AppWidgetProviderInfo ו מחייב את המאפיינים הבאים:

  • android:name: מציין את שם המטא-נתונים. כדאי להשתמש android.appwidget.provider כדי לזהות את הנתונים בתור מתאר AppWidgetProviderInfo.
  • android:resource: מציין את המשאב AppWidgetProviderInfo המיקום.

הטמעת המחלקה AppWidgetProvider

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

onUpdate()
התכונה הזו נקראת לעדכון הווידג'ט במרווחי הזמן המוגדרים על ידי updatePeriodMillis ב-AppWidgetProviderInfo. לעיון בטבלה שמתארים מאפייני ווידג'ט נוספים בדף הזה עבור מידע נוסף.
השיטה הזו נקראת גם כשהמשתמש מוסיף את הווידג'ט, אז היא מבצעת את הגדרה חיונית, כמו הגדרת גורמים מטפלים באירועים View אובייקטים או משימות התחלה לטעינת נתונים אליהם מוצגות בווידג'ט. עם זאת, אם מצהירים על פעילות של תצורה ללא הדגל configuration_optional, לשיטה הזו לא מתבצעת קריאה כשהמשתמש מוסיף את הווידג'ט, אבל נקרא אותו בעדכונים הבאים. זו אחריות לפעילות ההגדרות לבצע את העדכון הראשון, הושלמה. מידע נוסף זמין במאמר איך לאפשר למשתמשים להגדיר ווידג'טים של אפליקציות.
הקריאה החוזרת החשובה ביותר היא onUpdate(). אפשר לעיין בקטע טיפול באירועים באמצעות onUpdate() כיתה בדף הזה לקבלת מידע נוסף.
onAppWidgetOptionsChanged()

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

  • OPTION_APPWIDGET_MIN_WIDTH: מכיל את הגבול התחתון של הרוחב, ביחידות dp, של מופע ווידג'ט.
  • OPTION_APPWIDGET_MIN_HEIGHT: מכיל את הגבול התחתון של הגובה, ביחידות dp, של מופע ווידג'ט.
  • OPTION_APPWIDGET_MAX_WIDTH: מכיל את הגבול העליון של הרוחב, ביחידות dp, של מופע ווידג'ט.
  • OPTION_APPWIDGET_MAX_HEIGHT: מכיל את הגבול העליון של הגובה, ביחידות dp, של מופע ווידג'ט.
  • OPTION_APPWIDGET_SIZES: מכיל את רשימת הגדלים האפשריים (List<SizeF>), ביחידות dp, לווידג'ט הזה יכולה לקחת אותו. התכונה הושקה ב-Android 12.
onDeleted(Context, int[])

האפשרות הזו מופעלת בכל פעם שנמחק ווידג'ט ממארח הווידג'טים.

onEnabled(Context)

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

onDisabled(Context)

האפשרות הזו מופעלת כאשר המופע האחרון של הווידג'ט נמחק מארח ווידג'טים. כאן מנקים את כל העבודה שהתבצעה בonEnabled(Context), כמו מחיקה של מסד נתונים זמני.

onReceive(Context, Intent)

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

עליך להצהיר על הטמעת הכיתה AppWidgetProvider כשידור של מקלט באמצעות הרכיב <receiver> בAndroidManifest. ראו הצהרה על במניפסט שבדף הזה.

טיפול באירועים באמצעות המחלקה onUpdate()

הקריאה החוזרת החשובה ביותר של AppWidgetProvider היא onUpdate(), כי היא נשלחת קריאה כשכל ווידג'ט מתווסף למארח, אלא אם משתמשים בהגדרה פעילות ללא הדגל configuration_optional. אם בווידג'ט אפשר להשתמש אירועי אינטראקציה של משתמשים, ואז רושמים את הגורמים המטפלים באירועים בקריאה החוזרת (callback). אם המיקום הווידג'ט לא יוצר קבצים או מסדי נתונים זמניים ולא מבצע פעולות אחרות שדורש ניקוי, אז onUpdate() עשויה להיות שיטת הקריאה החוזרת היחידה צריך להגדיר.

לדוגמה, אם אתם רוצים ווידג'ט עם לחצן שמפעיל פעילות מקישים, אפשר להשתמש בשיטה הבאה להטמעה של AppWidgetProvider:

Kotlin

class ExampleAppWidgetProvider : AppWidgetProvider() {

    override fun onUpdate(
            context: Context,
            appWidgetManager: AppWidgetManager,
            appWidgetIds: IntArray
    ) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        appWidgetIds.forEach { appWidgetId ->
            // Create an Intent to launch ExampleActivity.
            val pendingIntent: PendingIntent = PendingIntent.getActivity(
                    /* context = */ context,
                    /* requestCode = */  0,
                    /* intent = */ Intent(context, ExampleActivity::class.java),
                    /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
            )

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            val views: RemoteViews = RemoteViews(
                    context.packageName,
                    R.layout.appwidget_provider_layout
            ).apply {
                setOnClickPendingIntent(R.id.button, pendingIntent)
            }

            // Tell the AppWidgetManager to perform an update on the current
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

Java

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        // Perform this loop procedure for each widget that belongs to this
        // provider.
        for (int i=0; i < appWidgetIds.length; i++) {
            int appWidgetId = appWidgetIds[i];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(
                /* context = */ context,
                /* requestCode = */ 0,
                /* intent = */ intent,
                /* flags = */ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
            );

            // Get the layout for the widget and attach an onClick listener to
            // the button.
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.example_appwidget_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);

            // Tell the AppWidgetManager to perform an update on the current app
            // widget.
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

AppWidgetProvider מגדיר רק את השיטה onUpdate(), באמצעותה כדי ליצור PendingIntent שיופעל Activity ומצרף אותו באמצעות setOnClickPendingIntent(int, PendingIntent). היא כוללת לולאה שחוזרת על עצמה כל ערך ב-appWidgetIds, שהוא מערך של מזהים שמזהים כל ווידג'ט שנוצר על ידי הספק הזה. אם המשתמש יוצר יותר ממופע אחד של הווידג'ט, אז כולם מתעדכנים בו-זמנית. עם זאת, רק לוח זמנים אחד של updatePeriodMillis מנוהלת עבור כל המופעים של הווידג'ט. לדוגמה, אם לוח הזמנים לעדכון מוגדרת לכל שעתיים, ונוסף מופע שני של הווידג'ט שעה אחרי הראשונה, ואז שניהם מעודכנים בתקופה שהוגדרה על ידי המערכת תתעלם מתקופת העדכון הראשונה. שניהם מתעדכנים כל שתיים ולא בכל שעה.

לצפייה ExampleAppWidgetProvider.java כדי לקבל פרטים נוספים על הכיתה.

קבלת כוונות שידור של ווידג'ט

AppWidgetProvider הוא שיעור נוחות. אם רוצים לקבל את הווידג'ט שידורים חיים ישירות, אפשר להטמיע BroadcastReceiver משלך או לשנות מברירת המחדל ה קריאה חוזרת (callback) של onReceive(Context,Intent). הכוונות צריכות להיות חשובות הבאים:

יצירת הפריסה של הווידג'ט

עליך להגדיר פריסה ראשונית לווידג'ט ב-XML ולשמור אותה בקובץ ה- של הפרויקט בספריית res/layout/. ראו עיצוב לפרטים נוספים.

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

RemoteViews תומך גם ב-ViewStub, שהוא View בלתי נראה בגודל אפס, שאפשר להשתמש בו כדי לניפוח פריסה בזמן הריצה.

תמיכה בהתנהגות של שמירת מצב

ב-Android 12 נוספה תמיכה בהתנהגות של שמירת מצב באמצעות האפשרויות הבאות רכיבים קיימים:

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

דוגמה לווידג&#39;ט של רשימת קניות שמציג התנהגות עם מצב מסוים
איור 3. דוגמה להתנהגות של מצב מסוים.

הקוד לדוגמה הבא מראה איך להטמיע את הרכיבים האלה.

Kotlin

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true)

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2)

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
        R.id.my_checkbox,
        RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent)
)

Java

// Check the view.
remoteView.setCompoundButtonChecked(R.id.my_checkbox, true);

// Check a radio group.
remoteView.setRadioGroupChecked(R.id.my_radio_group, R.id.radio_button_2);

// Listen for check changes. The intent has an extra with the key
// EXTRA_CHECKED that specifies the current checked state of the view.
remoteView.setOnCheckedChangeResponse(
    R.id.my_checkbox,
    RemoteViews.RemoteResponse.fromPendingIntent(onCheckedChangePendingIntent));

צריך לספק שתי פריסות: אחת למכשיר טירגוט עם Android 12 או גבוה יותר ב-res/layout-v31, והטירגוט השני הקודם Android מגרסה 11 ומטה בתיקיית ברירת המחדל res/layout.

מומלץ להטמיע פינות מעוגלות

ב-Android 12 מוצגים הפרמטרים הבאים של המערכת כדי להגדיר את: הרדיוס של הפינות המעוגלות של הווידג'ט:

  • system_app_widget_background_radius: הרדיוס של רקע הווידג'ט, שאף פעם לא גדול יותר 28dp

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

בדוגמה הבאה מוצג ווידג'ט שמשתמש בו system_app_widget_background_radius לפינה של הווידג'ט system_app_widget_inner_radius לתצוגות בתוך הווידג'ט.

ווידג&#39;ט שמציג רדיוס של רקע הווידג&#39;ט והתצוגות בתוך הווידג&#39;ט
איור 4. פינות מעוגלות.

1 פינת הווידג'ט.

2 פינת תצוגה בתוך הווידג'ט.

שיקולים חשובים לגבי פינות מעוגלות

  • מרכזי אפליקציות של צד שלישי ויצרני מכשירים יכולים לבטל את הפרמטר system_app_widget_background_radius יהיה קטן מ-28dp. הערך של הפרמטר system_app_widget_inner_radius הוא תמיד 8dp פחות מ- הערך של system_app_widget_background_radius.
  • אם בווידג'ט לא נעשה שימוש ב-@android:id/background או בהגדרת רקע שמקצר את התוכן שלו לפי המתאר — באמצעות android:clipToOutline מוגדרת ל-true - מרכז האפליקציות מזהה באופן אוטומטי את הרקע קליפים את הווידג'ט באמצעות מלבן עם פינות מעוגלות של עד 16dp. בקטע מוודאים שהווידג'ט תואם Android 12.

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

/values/attrs.xml

<resources>
  <attr name="backgroundRadius" format="dimension" />
</resources>

/values/styles.xml

<resources>
  <style name="MyWidgetTheme">
    <item name="backgroundRadius">@dimen/my_background_radius_dimen</item>
  </style>
</resources>

/values-31/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="@android:style/Theme.DeviceDefault.DayNight">
    <item name="backgroundRadius">@android:dimen/system_app_widget_background_radius</item>
  </style>
</resources>

/drawable/my_widget_background.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="rectangle">
  <corners android:radius="?attr/backgroundRadius" />
  ...
</shape>

/layout/my_widget_layout.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  ...
  android:background="@drawable/my_widget_background" />