תחילת העבודה עם כרטיסי מידע


כדי להתחיל לספק משבצות מהאפליקציה, צריך לכלול את יחסי התלות הבאים בקובץ build.gradle של האפליקציה.

Groovy

dependencies {
    // Use to implement support for wear tiles
    implementation "androidx.wear.tiles:tiles:1.6.2"

    // Use to utilize standard components and layouts in your tiles
    implementation "androidx.wear.protolayout:protolayout:1.4.2"

    // Use to utilize components and layouts with Material Design in your tiles
    implementation "androidx.wear.protolayout:protolayout-material:1.4.2"

    // Use to include dynamic expressions in your tiles
    implementation "androidx.wear.protolayout:protolayout-expression:1.4.2"

    // Use to preview wear tiles in your own app
    debugImplementation "androidx.wear.tiles:tiles-renderer:1.6.2"

    // Use to fetch tiles from a tile provider in your tests
    testImplementation "androidx.wear.tiles:tiles-testing:1.6.2"
}

Kotlin

dependencies {
    // Use to implement support for wear tiles
    implementation("androidx.wear.tiles:tiles:1.6.2")

    // Use to utilize standard components and layouts in your tiles
    implementation("androidx.wear.protolayout:protolayout:1.4.2")

    // Use to utilize components and layouts with Material Design in your tiles
    implementation("androidx.wear.protolayout:protolayout-material:1.4.2")

    // Use to include dynamic expressions in your tiles
    implementation("androidx.wear.protolayout:protolayout-expression:1.4.2")

    // Use to preview wear tiles in your own app
    debugImplementation("androidx.wear.tiles:tiles-renderer:1.6.2")

    // Use to fetch tiles from a tile provider in your tests
    testImplementation("androidx.wear.tiles:tiles-testing:1.6.2")
}

מושגים מרכזיים

משבצות לא בנויות כמו אפליקציות ל-Android, והן משתמשות במושגים שונים:

  • תבניות פריסה: מגדירות את הסידור הכללי של הרכיבים החזותיים במסך. כדי לעשות את זה, משתמשים בפונקציה primaryLayout().
  • רכיבי פריסה: מייצגים רכיב גרפי בודד, כמו כפתור או כרטיס, או כמה רכיבים כאלה שמקובצים יחד באמצעות עמודה, buttonGroup או רכיב דומה. הם מוטמעים בתוך תבנית פריסה.
  • משאבים: אובייקטים מסוג ResourceBuilders.Resources מורכבים ממפה של צמדי מפתח/ערך של משאבי Android (תמונות) שנדרשים כדי ליצור פריסה, ומגרסה.
  • ציר זמן: אובייקט TimelineBuilders.Timeline הוא רשימה של מופע אחד או יותר של אובייקט פריסה. אתם יכולים לספק מנגנונים וביטויים שונים כדי לציין מתי המעבד (renderer) צריך לעבור מאובייקט פריסה אחד לאחר, למשל כדי להפסיק להציג פריסה בזמן מסוים.
  • מצב: מבנה נתונים מסוג StateBuilders.State שמועבר בין המשבצת לאפליקציה, כדי לאפשר לשני הרכיבים לתקשר זה עם זה. לדוגמה, אם לוחצים על כפתור במשבצת, המצב מכיל את המזהה של הכפתור. אפשר גם להחליף סוגי נתונים באמצעות מפה.
  • משבצת: אובייקט מסוג TileBuilders.Tile שמייצג משבצת, ומורכב מציר זמן, מזהה גרסת משאבים, מרווח עדכניות ומצב.
  • ‫Protolayout: המונח הזה מופיע בשם של מחלקות שונות שקשורות למשבצות, ומתייחס לספריית Wear OS Protolayout – ספריית גרפיקה שמשמשת בפלטפורמות שונות של Wear OS.

יצירת משבצת

שימוש ב-Material3TileService (מומלץ)

כשיוצרים משבצות ב-Material 3 (גרסה androidx.wear.tiles:tiles:1.6.0 ואילך), תמיד צריך להרחיב את Material3TileService במקום את המחלקה TileService ברמה נמוכה יותר. ‫Material3TileService מספקת ארכיטקטורה מבוססת-דעה שמתמקדת ב-Kotlin ומפשטת את פיתוח המשבצות:

  • קורוטינות מובנות של Kotlin: מטמיעים פונקציית השהיה אחת (MaterialScope.tileResponse(requestParams: TileRequest): Tile) במקום להשתמש ב-ListenableFuture ולבטל את onTileRequest().
  • MaterialScope מוגדר מראש: tileResponse() פועל עם MaterialScope בתור המקבל שלו (מוגדר באמצעות פרמטרים של בנאי כמו allowDynamicTheme ו-defaultColorScheme), כך שאין צורך לעטוף את הפריסה בקריאה מיותרת ל-materialScope().
  • רישום משאבים בקריאה אחת: כולל את ProtoLayoutScope כדי לרשום באופן אוטומטי משאבי תמונות מוטבעות ולהחזיר גם את פריסת המשבצות וגם את המשאבים בקריאה אחת של System Binder. ‫Material3TileService מטפל במשאבים באופן אוטומטי (final onTileResourcesRequest()), לכן אל תבטלו את onTileResourcesRequest().
class MyTileService : Material3TileService() {

    override suspend fun MaterialScope.tileResponse(requestParams: TileRequest): Tile =
        tile(
            timeline =
            Timeline.fromLayoutElement(
                primaryLayout(
                    mainSlot = {
                        text("Hello, World!".layoutString, typography = BODY_LARGE)
                    }
                )
            )
        )
}

ארכיטקטורת TileService בסיסית

‫Material3TileService מבוסס על המחלקה הבסיסית TileService, שבה משתמשים בשאר הדוגמאות במדריך הזה כדי להמחיש מושגים בסיסיים.

כדי לספק משבצת מהאפליקציה, צריך להטמיע שירות מסוג TileService ולרשום אותו במניפסט. על סמך זה, המערכת מבקשת את המשבצות הנדרשות במהלך קריאות ל-onTileRequest() ואת המשאבים במהלך קריאות ל-onTileResourcesRequest().

class MyTileService : TileService() {

    override fun onTileRequest(requestParams: RequestBuilders.TileRequest) =
        Futures.immediateFuture(
            Tile.Builder()
                .setResourcesVersion(RESOURCES_VERSION)
                .setTileTimeline(
                    Timeline.fromLayoutElement(
                        materialScope(this, requestParams.deviceConfiguration) {
                            primaryLayout(
                                mainSlot = {
                                    text("Hello, World!".layoutString, typography = BODY_LARGE)
                                }
                            )
                        }
                    )
                )
                .build()
        )

    override fun onTileResourcesRequest(requestParams: ResourcesRequest) =
        Futures.immediateFuture(Resources.Builder().setVersion(RESOURCES_VERSION).build())
}

לאחר מכן, מוסיפים שירות בתוך התג <application> של הקובץ AndroidManifest.xml.

<service
    android:name=".snippets.m3.tile.MyTileService"
    android:label="@string/tile_label"
    android:description="@string/tile_description"
    android:icon="@mipmap/ic_launcher"
    android:exported="true"
    android:permission="com.google.android.wearable.permission.BIND_TILE_PROVIDER">
    <intent-filter>
        <action android:name="androidx.wear.tiles.action.BIND_TILE_PROVIDER" />
    </intent-filter>

    <meta-data android:name="androidx.wear.tiles.PREVIEW"
        android:resource="@drawable/tile_preview" />
</service>

ההרשאה ומסנן ה-Intent רושמים את השירות הזה כספק משבצות.

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

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

משבצת ב-Wear OS שנוצרה באמצעות Material 3, עם הטקסט &quot;Hello World&quot;.
תרשים 1. "Hello World".

דוגמה מלאה מופיעה בדוגמת הקוד ב-GitHub או ב-Codelab.

יצירת ממשק משתמש לכפתורים

רכיבי ממשק המשתמש של Material 3 Expressive נוצרים באמצעות גישה מובנית שמבוססת על תבנית ה-builder למניעת שגיאות הקלדה של Kotlin.

פריסה

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

כדי ליצור את הפריסה:

  1. הפעלת היקף של Material Design: מפעילים את הפונקציה materialScope() ומספקים את הפרמטרים הנדרשים context ו-deviceConfiguration. אפשר לכלול פרמטרים אופציונליים, כמו allowDynamicTheme ו-defaultColorScheme. הערך של allowDynamicTheme הוא true כברירת מחדל, והערך של defaultColorScheme מייצג את ColorScheme שמשמש כשצבעים דינמיים לא זמינים – למשל כשהמשתמש השבית את התכונה – או כשהמכשיר לא תומך בה, או כשהערך של allowDynamicTheme הוא false). כשמשתמשים בממשקי API של ImageResource כמו backgroundImage() ב-TileService בהתאמה אישית, צריך להפעיל במקום זאת את materialScopeWithResources().

  2. בניית ממשק המשתמש בתוך ההיקף: צריך להגדיר את כל רכיבי ממשק המשתמש של פריסת משבצת נתונה בתוך הלמבדה של קריאת materialScope()‎ אחת ברמה העליונה. הפונקציות האלה של הרכיבים, כמו primaryLayout() ו-textEdgeButton(), הן פונקציות של תוספים ב-MaterialScope והן זמינות רק כשקוראים להן בהיקף של המקלט הזה.

    materialScope(
        context = context,
        deviceConfiguration =
        requestParams.deviceConfiguration, // requestParams is passed to onTileRequest
        defaultColorScheme = myFallbackColorScheme
    ) {
        // inside the MaterialScope, you can call functions like primaryLayout()
        primaryLayout(
            titleSlot = { text(text = "Title".layoutString) },
            mainSlot = { text(text = "Main Content".layoutString) },
            bottomSlot = {
                textEdgeButton(
                    labelContent = { text("Action".layoutString) },
                    onClick = clickable()
                )
            }
        )
    }

מכונות מזל

ב-M3, פריסת המשבצות משתמשת בגישה בהשראת Compose, שכוללת שלושה משבצות נפרדות. מלמעלה למטה, אלה השלבים:

  1. titleSlot, בדרך כלל לכותרת ראשית.
  2. ה-mainSlot, לתוכן הליבה.
  3. bottomSlot, שמשמשת בדרך כלל לפעולות או למידע נוסף. כאן גם מופיע כפתור הקצה.
פריסת משבצות שמוצגים בה titleSlot, ‏ mainSlot ו-bottomSlot
איור 2. titleSlot,‏ mainSlot ו-bottomSlot.

התוכן של כל משבצת הוא:

  • ‫titleSlot (אופציונלי): בדרך כלל כמה מילים שנוצרו על ידי text().
  • ‫mainSlot (חובה): רכיבים שמסודרים במבנים כמו שורות, עמודות וקבוצות של כפתורים. אפשר גם להטמיע את הרכיבים האלה באופן רקורסיבי אחד בתוך השני. לדוגמה, עמודה יכולה להכיל שורות.
  • ‫bottomSlot (אופציונלי): בדרך כלל מכיל כפתור צמוד-קצה או תווית טקסט.

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

רכיבי ממשק משתמש

הספרייה protolayout-material3 מספקת מספר גדול של רכיבים שתוכננו בהתאם למפרטים של Material 3 Expressive ולהמלצות לממשק המשתמש.

כפתורים

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

  • ‫textButton()‎: כפתור עם משבצת אחת לתוכן טקסט (קצר)
  • ‫iconButton()‎: כפתור עם משבצת אחת שמייצגת סמל
  • ‫avatarButton()‎: כפתור בצורת גלולה שמציע עד שלושה מיקומים לתוכן שמייצג תווית ותווית משנית שמוצגות זו מעל זו, ותמונה (אווטאר) לידן
  • ‫imageButton()‎: כפתור תמונה שאפשר ללחוץ עליו, שלא מציע משבצות נוספות, רק תמונה (לדוגמה backgroundImage כרקע)
  • ‫compactButton()‎: כפתור קומפקטי עם עד שני מיקומים לתוכן שמוצג בצורה אופקית, שמייצג סמל וטקסט לידו
  • ‫button()‎: כפתור בצורת גלולה עם עד שלושה מיקומים לתוכן שמייצג תווית ותווית משנית שמוצגות זו מעל זו, וסמל לידן

כפתורי Edge

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

  • ‫iconEdgeButton()‎: כפתור קצה שמציע משבצת אחת לסמל או לתוכן קטן ועגול דומה
  • ‫textEdgeButton()‎: כפתור קצה שמציע משבצת אחת לטקסט או לתוכן ארוך ורחב דומה

כרטיסים

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

  • ‫titleCard()‎: שקופית פתיחה עם משבצת אחת עד שלוש, בדרך כלל מבוססת טקסט
  • appCard(): כרטיס אפליקציה המציע עד חמישה משבצות, בדרך כלל מבוססות טקסט
  • textDataCard()‎: כרטיס נתונים שמציע עד שלוש משבצות בערימה אנכית, בדרך כלל מבוססות על טקסט או מספרים
  • ‫iconDataCard()‎: כרטיס נתונים שמציע עד שלוש משבצות שמוצגות זו מעל זו, בדרך כלל מבוססות על טקסט או מספרים, עם סמל
  • ‫graphicDataCard()‎: כרטיס נתונים גרפיים שמציע משבצת לנתונים גרפיים, כמו אינדיקטור התקדמות, ועד שתי משבצות בערימה אנכית, בדרך כלל לתיאורי טקסט

אינדיקטורים להתקדמות

רכיבי פריסה של קבוצה

  • ‫buttonGroup()‎: פריסת רכיבים שמציבה את הצאצאים שלה ברצף אופקי
  • ‫primaryLayout()‎: פריסה במסך מלא שמייצגת סגנון פריסה מומלץ של M3, שהוא רספונסיבי ומטפל במיקום של הרכיבים, יחד עם השוליים והריפוד המומלצים.

החלת עיצוב

ב-Material 3 Expressive, מערכת הצבעים מוגדרת לפי 29 תפקידי צבע סטנדרטיים, שמחולקים ל-6 קבוצות: ראשי, משני, שלישוני, שגיאה, משטח וקו מתאר.

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

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

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

val myColorScheme =
    ColorScheme(
        primary = Color.rgb(0, 0, 255).argb, // Blue
        onPrimary = Color.rgb(255, 255, 255).argb, // White
        // 27 more
    )

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    defaultColorScheme = myColorScheme
) {
    // If the user selects "no theme" in settings, myColorScheme is used.
    // Otherwise, the system-provided theme is used.
}

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

כדי לאלץ את המשבצות להופיע בערכת הצבעים שאתם מספקים, צריך להשבית את התמיכה בעיצוב דינמי על ידי הגדרת allowDynamicTheme ל-false:

materialScope(
    context = context,
    deviceConfiguration = requestParams.deviceConfiguration,
    allowDynamicTheme = false,
    defaultColorScheme = myColorScheme
) {
    // myColorScheme is *always* used.
}

צבע

כל רכיב בנפרד משתמש בקבוצת משנה של 29 תפקידי הצבעים שמוגדרים על ידי ColorScheme. לדוגמה, בכפתורים נעשה שימוש בעד ארבעה צבעים, שנלקחים כברירת מחדל מהקבוצה "primary" של ה-ColorScheme הפעיל:

טוקן של רכיב ButtonColors תפקיד ColorScheme
containerColor ראשי
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (אטימות 0.8)

במדריך לעיצוב צבעים מפורטות הנחיות להוספת צבעים לעיצובים של Wear OS.

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

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

  1. שימוש בפונקציית עזר לצבעים מוגדרים מראש משתמשים בפונקציות עזר כמו filledTonalButtonColors() כדי להחיל את הסגנונות הרגילים של הלחצנים ב-Material 3 Expressive. הפונקציות האלה יוצרות מופעים מוגדרים מראש של ButtonColors שממפים סגנונות נפוצים כמו filled,‏ tonal או outlined לתפקידים המתאימים מתוך ColorScheme הפעיל ב-MaterialScope. כך אפשר להחיל סגנונות עקביים בלי להגדיר ידנית כל צבע לסוגי כפתורים נפוצים.

    textEdgeButton(
        colors = filledButtonColors(), // default
        /* OR colors = filledTonalButtonColors() */
        /* OR colors = filledVariantButtonColors() */
        // ... other parameters
    )

    בכרטיסים, משתמשים בפונקציות המקבילות ממשפחת filledCardColors().

    אפשר גם לשנות את האובייקט ButtonColors שמוחזר על ידי פונקציות עזר באמצעות השיטה copy(), אם צריך לשנות רק טוקן אחד או שניים:

    textEdgeButton(
        colors =
        filledButtonColors()
            .copy(
                containerColor = colorScheme.tertiary,
                labelColor = colorScheme.onTertiary
            ),
        // ... other parameters
    )

  2. לספק במפורש תפקידי צבע חלופיים. יוצרים אובייקט ButtonColors משלכם ומעבירים אותו לרכיב. בכרטיסים, משתמשים באובייקט CardColors המקביל.

    textEdgeButton(
        colors =
        ButtonColors(
            // the materialScope makes colorScheme available
            containerColor = colorScheme.secondary,
            iconColor = colorScheme.secondaryDim,
            labelColor = colorScheme.onSecondary,
            secondaryLabelColor = colorScheme.onSecondary
        ),
        // ... other parameters
    )

  3. ציינו צבעים קבועים (השתמשו באפשרות הזו בזהירות). בדרך כלל מומלץ לציין צבעים לפי התפקיד הסמנטי שלהם (למשל, colorScheme.primary), אבל אפשר גם לציין ערכי צבעים ישירים. כדאי להשתמש בגישה הזו רק כשצריך, כי היא עלולה לגרום לחוסר עקביות עם העיצוב הכללי, במיוחד אם העיצוב משתנה באופן דינמי.

    textEdgeButton(
        colors = filledButtonColors().copy(
            containerColor = android.graphics.Color.RED.argb, // Using named colors
            labelColor = 0xFFFFFF00.toInt().argb // Using a hex code for yellow
        ),
        // ... other parameters
    )

טיפוגרפיה

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

כדי ליצור עקביות חזותית בפלטפורמת Wear OS ולשפר את הביצועים, כל הטקסט בכרטיסי המידע מוצג באמצעות גופן שסופק על ידי המערכת. כלומר, המשבצות לא תומכות במשפחות גופנים בהתאמה אישית. ב-Wear OS מגרסה 6 ומעלה, זהו גופן ספציפי ל-OEM. ברוב המקרים זה יהיה גופן משתנה, שמציע חוויה אקספרסיבית יותר ושליטה מפורטת יותר.

כדי ליצור סגנון טקסט, בדרך כלל משתמשים ב-method‏ text() בשילוב עם קבועים טיפוגרפיים. הרכיב הזה מאפשר לכם להשתמש בתפקידי טיפוגרפיה מוגדרים מראש ב-Material 3 Expressive, כדי שהמשבצת תתאים לשיטות המומלצות המקובלות בתחום הטיפוגרפיה בנוגע לקריאוּת ולהיררכיה. הספרייה מציעה קבוצה של 18 קבועים סמנטיים של טיפוגרפיה, כמו BODY_MEDIUM. הקבועים האלה משפיעים גם על צירי גופן אחרים מלבד הגודל.

text(
    text = "Hello, World!".layoutString,
    typography = BODY_MEDIUM,
)

כדי לקבל יותר שליטה, אתם יכולים להוסיף הגדרות. ב-Wear OS מגרסה 6 ואילך, סביר להניח שייעשה שימוש בגופן משתנה, שאפשר לשנות לפי הצירים נטוי, משקל, רוחב ועיגול. אפשר לשלוט בצירים האלה באמצעות הפרמטר settings:

text(
    text = "Hello, World".layoutString,
    italic = true,

    // Use elements defined in androidx.wear.protolayout.LayoutElementBuilders.FontSetting
    settings =
    listOf(
        weight(500),
        width(100F),
        roundness(100)
    ),
)

לבסוף, אם אתם צריכים לשלוט בגודל או במרווח בין האותיות (לא מומלץ), השתמשו ב-basicText()‎ במקום ב-text()‎, וצרו ערך למאפיין fontStyle באמצעות fontStyle()‎.

צורה ושוליים

אפשר לשנות את רדיוס הפינה של כמעט כל רכיב באמצעות המאפיין shape שלו. הערכים מגיעים מהמאפיין shapes של MaterialScope:

textButton(
    height = expand(),
    width = expand(),
    shape = shapes.medium, // OR another value like shapes.full
    colors = filledVariantButtonColors(),
    labelContent = { text("Hello, World!".layoutString) },
)

אחרי שמשנים את הצורה של רכיב, אם לדעתכם יש יותר מדי או פחות מדי מקום מסביב לקצה של המסך, אתם יכולים לשנות את השוליים באמצעות הפרמטר margin של primaryLayout():

primaryLayout(
    mainSlot = {
        textButton(
            shape = shapes.small,
            /* ... */
        )
    },
    // margin constants defined in androidx.wear.protolayout.material3.PrimaryLayoutMargins
    margins = MAX_PRIMARY_LAYOUT_MARGIN,
)

קשתות

אלה הצאצאים של הקונטיינר Arc שנתמכים:

  • ‫ArcLine: עיבוד של קו מעוקל מסביב לקשת.
  • ‫ArcText: עיבוד של טקסט מעוקל בקשת.
  • ‫ArcAdapter: עיבוד של רכיב פריסה בסיסי בקשת, שמשורטט כמשיק לקשת.

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

גורמי שינוי

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

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

לדוגמה, אפשר להתאים אישית את המראה והמטא-נתונים שמוגדרים כברירת מחדל של Image, כמו שמוצג בדוגמת הקוד הבאה:

private fun myImage(): LayoutElement =
    Image.Builder()
        .setWidth(dp(24f))
        .setHeight(dp(24f))
        .setResourceId("image_id")
        .setModifiers(
            Modifiers.Builder()
                .setBackground(Background.Builder().setColor(argb(0xFFFF0000.toInt())).build())
                .setPadding(ModifiersBuilders.Padding.Builder().setStart(dp(12f)).build())
                .setSemantics(Semantics.Builder().setContentDescription("Image description").build())
                .build()
        )
        .build()

Spannables

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

קונטיינר מסוג Spannable מלא ב-Span צאצאים. אסור להשתמש בצאצאים אחרים או במופעים מקוננים של Spannable.

יש שני סוגים של צאצאים של Span:

  • ‫SpanText: עיבוד טקסט בסגנון ספציפי.
  • ‫SpanImage: הצגת תמונה בשורה עם טקסט.

לדוגמה, אפשר להציג את המילה "world" בכתב נטוי במשבצת "Hello world" ולהוסיף תמונה בין המילים, כמו בדוגמת הקוד הבאה:

private fun mySpannable(): LayoutElement =
    LayoutElementBuilders.Spannable.Builder()
        .addSpan(SpanText.Builder().setText("Hello ").build())
        .addSpan(SpanImage.Builder().setWidth(dp(24f)).setHeight(dp(24f)).setResourceId("image_id").build())
        .addSpan(
            SpanText.Builder()
                .setText("world")
                .setFontStyle(FontStyle.Builder().setItalic(true).build())
                .build()
        )
        .build()

עבודה עם משאבים

למשבצות אין גישה למשאבים של האפליקציה. כלומר, אי אפשר להעביר מזהה תמונה של Android לרכיב פריסה של Image ולצפות שהוא יפעל. במקום זאת, צריך לשנות את ה-method‏ onTileResourcesRequest() ולספק את המשאבים באופן ידני.

יש שתי דרכים לספק תמונות בשיטה onTileResourcesRequest():

override fun onTileResourcesRequest(
    requestParams: ResourcesRequest
) = Futures.immediateFuture(
    Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping(
            "image_from_resource",
            ResourceBuilders.ImageResource.Builder()
                .setAndroidResourceByResId(
                    ResourceBuilders.AndroidImageResourceByResId.Builder()
                        .setResourceId(R.drawable.ic_walk)
                        .build()
                ).build()
        )
        .addIdToImageMapping(
            "image_inline",
            ResourceBuilders.ImageResource.Builder()
                .setInlineResource(
                    ResourceBuilders.InlineImageResource.Builder()
                        .setData(imageAsByteArray)
                        .setWidthPx(48)
                        .setHeightPx(48)
                        .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                        .build()
                ).build()
        ).build()
)

רשימת משימות לתמונות של תצוגה מקדימה של כרטיסי מידע

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

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

  • משקף את העיצוב העדכני. התצוגה המקדימה צריכה לייצג במדויק את העיצוב העדכני ביותר של המשבצת.
  • שימוש במאפיינים המומלצים. כדי לספק את איכות התצוגה הטובה ביותר וחוויית משתמש טובה, המידות של התמונה המקדימה צריכות להיות 400 פיקסלים על 400 פיקסלים.
  • ערכת צבעים סטטית. משתמשים בערכת הצבעים הסטטית של המשבצת, ולא בערכה דינמית.
  • כולל את סמל האפליקציה. מוודאים שסמל האפליקציה מופיע בחלק העליון של התמונה בתצוגה המקדימה.
  • מציג את מצב הטעינה/ההתחברות. התצוגה המקדימה צריכה להציג מצב "טעון" או "מחובר" שפועל באופן מלא, ולהימנע מתוכן ריק או מתוכן של פלייסהולדר.
  • שימוש בכללי פתרון משאבים להתאמה אישית (אופציונלי). כדאי להשתמש בכללי הרזולוציה של המשאבים ב-Android כדי לספק תצוגות מקדימות שתואמות להגדרות של גודל המסך, השפה או הלוקאל של המכשיר. האפשרות הזו שימושית במיוחד אם המשבצת נראית אחרת במכשירים שונים.