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

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

כדי לשפר את חוויית השימוש בכלי לבחירת הווידג'טים באפליקציה, כדאי לספק תצוגה מקדימה של הווידג'ט שנוצר במכשירי Android מגרסה 15 ואילך, תצוגה מקדימה של הווידג'ט בהתאמת גודל (צריך לציין previewLayout) במכשירי Android מגרסה 12 עד גרסה 14, ו-previewImage בגרסאות קודמות.

יש מידע נוסף במאמר Enrich your app with live updates and widgets (הוספת ווידג'טים ועדכונים בזמן אמת לאפליקציה) ב-YouTube.

הגדרת האפליקציה לתצוגות מקדימות של ווידג'טים שנוצרו

כדי להציג תצוגה מקדימה של ווידג'טים שנוצרו במכשיר עם Android מגרסה 15 ואילך, קודם צריך להגדיר את הערך compileSdk ל-35 או לערך גבוה יותר בקובץ build.gradle של המודול, כדי לאפשר את האפשרות RemoteViews בכלי לבחירת ווידג'טים.

אחר כך, אפליקציות יכולות להשתמש ב-setWidgetPreview ב-GlanceAppWidgetManager או ב-AppWidgetManager. כדי למנוע ניצול לרעה ולצמצם את הסיכונים לבריאות המערכת, setWidgetPreview הוא API עם הגבלת קצב של יצירת בקשות. מגבלת ברירת המחדל היא בערך שתי שיחות בשעה.

יצירת תצוגה מקדימה מעודכנת באמצעות Jetpack Glance

כדי להוסיף ווידג'טים שנוצרו באמצעות Jetpack Glance:

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

  2. מבקשים להפעיל את GlanceAppWidgetManager.setWidgetPreviews כדי ליצור ולפרסם את התצוגה המקדימה.

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

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

פתרון בעיות בתצוגות מקדימות שנוצרו

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

הסיבה לכך היא שב-Android, כברירת מחדל, מוצגים רק רכיבי שניתנים להגדרה שגלויים בגודל המינימלי של הווידג'ט. במילים אחרות, מערכת Android מגדירה כברירת מחדל את previewSizeMode כ-SizeMode.Single. הוא משתמש ב-android:minHeight וב-android:minWidth בקובץ ה-XML של ספק הווידג'ט של האפליקציה כדי לקבוע אילו רכיבים שניתן להגדיר אפשר לשלוף.

כדי לפתור את הבעיה, צריך לבטל את ההגדרה של previewSizeMode ב-GlanceAppWidget ולהגדיר אותה ל-SizeMode.Responsive, ולציין קבוצה של ערכי DpSize. כך מערכת Android יודעת את כל גודלי הפריסה שהיא צריכה לעבד לתצוגה המקדימה, ומוודאת שכל הרכיבים יוצגו בצורה נכונה.

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

יצירת תצוגה מקדימה מעודכנת בלי Jetpack Glance

אפשר להשתמש ב-RemoteViews בלי Glance. בדוגמה הבאה משאב פריסת ווידג'ט בפורמט XML נטען ומוגדר כתצוגה מקדימה. כדי שהפונקציה setWidgetPreview תוצג כשיטה בקטע הקוד הזה, צריך להגדיר את הגדרת ה-build של compileSdk ל-35 ומעלה.

AppWidgetManager.getInstance(appContext).setWidgetPreview(
    ComponentName(
        appContext,
        ExampleAppWidgetReceiver::class.java
    ),
    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    RemoteViews("com.example", R.layout.widget_preview)
)

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

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

כדי להטמיע תצוגות מקדימות של ווידג'טים שניתן לשנות את הגודל שלהן, משתמשים במאפיין previewLayout של רכיב appwidget-provider כדי לספק פריסת XML במקום זאת:

<appwidget-provider
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>

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

מומלץ לציין את המאפיינים previewLayout ו-previewImage, כדי שהאפליקציה תוכל להשתמש ב-previewImage אם המכשיר של המשתמש לא תומך ב-previewLayout. המאפיין previewLayout מקבל עדיפות על פני המאפיין previewImage.

תאימות לדורות קודמים עם תצוגות מקדימות של ווידג'טים

כדי לאפשר לכלי לבחירת ווידג'טים ב-Android 11 (רמת API ‏30) ומטה להציג תצוגות מקדימות של הווידג'ט שלכם, או כגיבוי לתצוגות מקדימות שנוצרו, צריך לציין את המאפיין previewImage.

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

יצירת תצוגות מקדימות מדויקות שכוללות פריטים דינמיים

איור 1: תצוגה מקדימה של ווידג'ט שלא מציג פריטים ברשימה.

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

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

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

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

כדי להמחיש דוגמה ל-ListView, מתחילים בקובץ פריסה נפרד:

// res/layout/widget_preview.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:background="@drawable/widget_background"
   android:orientation="vertical">

    // Include the actual widget layout that contains ListView.
    <include
        layout="@layout/widget_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    // The number of fake items you include depends on the values you provide
    // for minHeight or targetCellHeight in the AppWidgetProviderInfo
    // definition.

    <TextView android:text="@string/fake_item1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

    <TextView android:text="@string/fake_item2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginVertical="?attr/appWidgetInternalPadding" />

</LinearLayout>

כשמספקים את מאפיין previewLayout של המטא-נתונים AppWidgetProviderInfo, צריך לציין את קובץ פריסת התצוגה המקדימה. עדיין צריך לציין את פריסת הווידג'ט בפועל במאפיין initialLayout ולהשתמש בפריסת הווידג'ט בפועל כשיוצרים RemoteViews בזמן ריצה.

<appwidget-provider
    previewLayout="@layout/widget_previe"
    initialLayout="@layout/widget_view" />

פריטים מורכבים ברשימה

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

נניח שיש פריט ברשימה שמוגדר ב-widget_list_item.xml ומורכב משני אובייקטים מסוג TextView:

<LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

    <TextView android:id="@id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_title" />

    <TextView android:id="@id/content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/fake_content" />
</LinearLayout>

כדי לספק פריטים מזויפים ברשימה, אפשר לכלול את הפריסה כמה פעמים, אבל אז כל הפריטים ברשימה יהיו זהים. כדי לספק פריטים ייחודיים לרשימה, פועלים לפי השלבים הבאים:

  1. יוצרים קבוצת מאפיינים לערכי הטקסט:

    <resources>
        <attr name="widgetTitle" format="string" />
        <attr name="widgetContent" format="string" />
    </resources>
    
  2. משתמשים במאפיינים האלה כדי להגדיר את הטקסט:

    <LinearLayout  xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
        <TextView android:id="@id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetTitle" />
    
        <TextView android:id="@id/content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="?widgetContent" />
    </LinearLayout>
    
  3. יוצרים כמה סגנונות שצריך לתצוגה המקדימה. מגדירים מחדש את הערכים בכל סגנון:

    <resources>
    
        <style name="Theme.Widget.ListItem">
            <item name="widgetTitle"></item>
            <item name="widgetContent"></item>
        </style>
        <style name="Theme.Widget.ListItem.Preview1">
            <item name="widgetTitle">Fake Title 1</item>
            <item name="widgetContent">Fake content 1</item>
        </style>
        <style name="Theme.Widget.ListItem.Preview2">
            <item name="widgetTitle">Fake title 2</item>
            <item name="widgetContent">Fake content 2</item>
        </style>
    
    </resources>
    
  4. משתמשים בסגנונות לפריטים המזויפים בפריסת התצוגה המקדימה:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:layout_width="match_parent"
       android:layout_height="wrap_content" ...>
    
        <include layout="@layout/widget_view" ... />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview1" />
    
        <include layout="@layout/widget_list_item"
            android:theme="@style/Theme.Widget.ListItem.Preview2" />
    
    </LinearLayout>