שיפור הווידג'ט

אנסה לכתוב
‫Jetpack Compose היא ערכת הכלים המומלצת לבניית ממשק משתמש ל-Android. איך יוצרים ווידג'טים באמצעות ממשקי API בסגנון Compose

בדף הזה מפורטים שיפורים אופציונליים לווידג'טים שזמינים החל מ-Android 12 (רמת API 31). התכונות האלה הן אופציונליות, אבל קל להטמיע אותן והן משפרות את חוויית המשתמשים בווידג'ט.

שימוש בצבעים דינמיים

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

יש שתי דרכים להשיג צבעים דינמיים:

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

דוגמאות למאפייני צבע שאפשר להשתמש בהם:

  • ?attr/primary
  • ?attr/primaryContainer
  • ?attr/onPrimary
  • ?attr/onPrimaryContainer

בדוגמה הבאה שבה נעשה שימוש בעיצוב Material 3, צבע העיצוב של המכשיר הוא 'סגלגל'. צבע המשנה ורקע הווידג'ט מותאמים למצב הבהיר והכהה, כמו שמוצג באיורים 1 ו-2.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="?attr/colorPrimaryContainer"
  android:theme="@style/Theme.Material3.DynamicColors.DayNight">

  <ImageView
    ...
    app:tint="?attr/colorPrimaryContainer"
    android:src="@drawable/ic_partly_cloudy" />

    <!-- Other widget content. -->

</LinearLayout>
ווידג&#39;ט בעיצוב בהיר
איור 1. ווידג'ט בעיצוב בהיר.
ווידג&#39;טים בעיצוב כהה
איור 2. ווידג'ט בעיצוב כהה.

תאימות לאחור של צבעים דינמיים

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

דוגמה לשימוש בעיצוב Material 3:

/values/styles.xml

<resources>
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight">
    <!-- Override default colorBackground attribute with custom color. -->
    <item name="android:colorBackground">@color/my_background_color</item>

    <!-- Add other colors/attributes. -->

  </style>
</resources>

/values-v31/styles.xml

<resources>
  <!-- Do not override any color attribute. -->
  <style name="MyWidgetTheme" parent="Theme.Material3.DynamicColors.DayNight" />
</resources>

/layout/my_widget_layout.xml

<resources>
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:background="?android:attr/colorBackground"
    android:theme="@style/MyWidgetTheme" />
</resources>

הפעלת תמיכה קולית

פעולות באפליקציה מאפשרות ל-Google Assistant להציג ווידג'טים בתגובה לפקודות קוליות רלוונטיות של המשתמשים. אם תגדירו את הווידג'ט כך שיגיב לכוונות מוכללות (BII), האפליקציה תוכל להציג באופן יזום ווידג'טים בממשקי Assistant כמו Android ו-Android Auto. המשתמשים יכולים להצמיד ווידג'טים שמוצגים על ידי Assistant למסך הבית, כדי לעודד אינטראקציה עתידית.

לדוגמה, אפשר להגדיר את הווידג'ט של סיכום האימון באפליקציית הכושר כדי למלא את הפקודות הקוליות של המשתמש שמפעילות את GET_EXERCISE_OBSERVATION BII. ‫Assistant מציג באופן יזום את הווידג'ט כשמשתמשים מפעילים את ה-BII הזה על ידי שליחת בקשות כמו "Ok Google, how many miles did I run this week on ExampleApp?‎" (אוקיי Google, כמה מיילים רצתי השבוע באפליקציה ExampleApp?)

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

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

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

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

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

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

אפליקציות יכולות להשתמש בשיטות AppWidgetManager,‏ setWidgetPreview ו-getWidgetPreview כדי לעדכן את המראה של הווידג'טים שלהן במידע עדכני ומותאם אישית.

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

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

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

AppWidgetManager.getInstance(appContext).setWidgetPreview(
    ComponentName(
        appContext,
        ExampleAppWidgetReceiver::class.java
    ),
    AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN,
    ExampleAppWidget().compose(
        context = appContext
    ),
)

יצירת תצוגה מקדימה מעודכנת בלי 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.

גישות מומלצות ליצירת תצוגות מקדימות מדויקות

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

<appwidget-provider
    ...
    android:previewLayout="@layout/my_widget_preview">
</appwidget-provider>
תמונה שרואים בה תצוגה מקדימה של ווידג&#39;ט
איור 3. תצוגה מקדימה של ווידג'ט שמופיעה כברירת מחדל באזור בגודל 3x3, אבל יכולה להתאים לאזור בגודל 3x1 בגלל פריסת ה-XML שלה.

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

  • הגדרת android:text="@string/my_widget_item_fake_1" לרכיבי TextView.

  • הגדרת תמונה או סמל של ברירת מחדל או placeholder, כמו android:src="@drawable/my_widget_icon", לרכיבי ImageView.

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

למידע על גישות מומלצות לתצוגות מקדימות מורכבות יותר שמכילות ListView,‏ GridView או StackView, אפשר לעיין במאמר יצירת תצוגות מקדימות מדויקות שכוללות פריטים דינמיים.

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

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

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

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

לווידג'טים צריך להיות שם ייחודי כשהם מוצגים בכלי לבחירת ווידג'טים.

השמות של הווידג'טים נטענים מהמאפיין label של רכיב receiver הווידג'ט בקובץ AndroidManifest.xml.

<receiver
    ….
   android:label="Memories">
     ….
</receiver>

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

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

תמונה שבה רואים את כלי בחירת הווידג&#39;טים, עם ווידג&#39;ט והתיאור שלו
איור 4. דוגמה לכלי לבחירת ווידג'טים שבו מוצג ווידג'ט והתיאור שלו.

מוסיפים תיאור לווידג'ט באמצעות המאפיין description של הרכיב &lt;appwidget-provider&gt;:

<appwidget-provider
    android:description="@string/my_widget_description">
</appwidget-provider>

אפשר להשתמש במאפיין descriptionRes בגרסאות קודמות של Android, אבל הוא לא נלקח בחשבון בבורר הווידג'טים.

הפעלת מעברים חלקים יותר

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

כדי להפעיל את המעבר המשופר הזה, משתמשים ב-@android:id/background או ב-android.R.id.background כדי לזהות את רכיב הרקע:

// Top-level layout of the widget.
<LinearLayout
    android:id="@android:id/background">
</LinearLayout>

האפליקציה שלך יכולה להשתמש ב-@android:id/background בגרסאות קודמות של Android בלי לגרום לבעיות, אבל המערכת מתעלמת מההרשאה הזו.

שימוש בשינוי בזמן ריצה של RemoteViews

החל מ-Android 12, אפשר להשתמש בכמה שיטות של RemoteViews כדי לשנות מאפיינים של RemoteViews בזמן ריצה. הרשימה המלאה של השיטות שנוספו מופיעה במאמר בנושא RemoteViews API.

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

Kotlin

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList())

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP)

Java

// Set the colors of a progress bar at runtime.
remoteView.setColorStateList(R.id.progress, "setProgressTintList", createProgressColorStateList());

// Specify exact sizes for margins.
remoteView.setViewLayoutMargin(R.id.text, RemoteViews.MARGIN_END, 8f, TypedValue.COMPLEX_UNIT_DP);