بدء استخدام الشاشات


لبدء توفير مربّعات من تطبيقك، أدرِج التبعيات التالية في ملف build.gradle الخاص بتطبيقك.

رائع

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

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

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

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

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

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

Kotlin

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

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

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

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

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

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

المفاهيم الرئيسية

لا يتم إنشاء البلاطات بالطريقة نفسها التي يتم بها إنشاء تطبيقات Android، وهي تستخدم مفاهيم مختلفة:

  • نماذج التنسيق: تحدّد الترتيب العام للعناصر المرئية على الشاشة. يتم ذلك من خلال الدالة primaryLayout().
  • عناصر التنسيق: تمثّل عنصرًا رسوميًا فرديًا، مثل زر أو بطاقة، أو عدة عناصر من هذا النوع مجمّعة معًا باستخدام عمود أو مجموعة أزرار أو ما شابه ذلك. وهي مضمّنة في نموذج تخطيط.
  • الموارد: تتألف عناصر ResourceBuilders.Resources من خريطة لأزواج المفتاح/القيمة الخاصة بموارد Android (الصور) المطلوبة لعرض تخطيط، ومن إصدار.
  • المخطّط الزمني: كائن TimelineBuilders.Timeline هو قائمة تتضمّن مثيلاً واحدًا أو أكثر من كائن التنسيق. يمكنك توفير آليات وتعبيرات مختلفة للإشارة إلى الوقت الذي يجب أن ينتقل فيه برنامج العرض من عنصر تصميم إلى آخر، مثل إيقاف عرض تصميم في وقت معيّن.
  • الحالة: هي بنية بيانات من النوع StateBuilders.State يتم تمريرها بين المربّع والتطبيق، وذلك لتمكين المكوّنَين من التواصل مع بعضهما البعض. على سبيل المثال، إذا تم النقر على زر في اللوحة، ستحتوي الحالة على رقم تعريف الزر. يمكنك أيضًا تبادل أنواع البيانات باستخدام خريطة.
  • المربّع: هو عنصر TileBuilders.Tile يمثّل مربّعًا ويتألف من مخطط زمني ورقم تعريف إصدار الموارد وفترة الحداثة والحالة.
  • Protolayout: يظهر هذا المصطلح في أسماء فئات مختلفة ذات صلة باللوحات، ويشير إلى مكتبة Protolayout لنظام التشغيل Wear OS، وهي مكتبة رسومات مستخدَمة في مساحات عرض مختلفة على Wear OS.

إنشاء مربّع

لتوفير مربّع من تطبيقك، عليك تنفيذ خدمة من النوع 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>

يسجّل الإذن وفلتر الأهداف هذه الخدمة كموفّر للّوحات.

يظهر للمستخدم رمز المورد والتصنيف والوصف والمعاينة عند إعداد مربّعات الشاشة على الهاتف أو الساعة. يُرجى العِلم أنّ مورد المعاينة يتوافق مع جميع محدّدات الموارد العادية في Android، لذا يمكن تغيير المعاينة وفقًا لعوامل مثل حجم الشاشة ولغة الجهاز. يمكنك الاطّلاع على قائمة التحقّق الخاصة بالمعاينة للحصول على اقتراحات إضافية.

انشر تطبيقك، ثم أضِف الشاشة إلى لوحة عرض الشاشات (تتوفّر أيضًا طريقة أسهل للمطوّرين لمعاينة الشاشة، ولكن يمكنك حاليًا تنفيذ ذلك يدويًا).

مربّع &quot;Hello World&quot;
الشكل 1. البلاطة "Hello World"

للاطّلاع على مثال كامل، راجِع نموذج الرمز البرمجي على GitHub أو التجربة العملية.

إنشاء واجهة مستخدم للمربّعات

يتم إنشاء عناصر واجهة المستخدم التعبيرية في Material 3 باستخدام نهج منظَّم يعتمد على نمط الإنشاء الآمن من حيث النوع في Kotlin.

التنسيق

للحصول على إرشادات حول مبادئ التصميم التي تستند إليها عملية إنشاء تنسيقات مربّعات شاشة فعّالة ومتجاوبة، يُرجى الاطّلاع على التنسيقات الشائعة للمربّعات.

لإنشاء تخطيطك، اتّبِع الخطوات التالية:

  1. بدء نطاق Material Design: استدعِ الدالة materialScope()، وقدِّم context وdeviceConfiguration المطلوبَين. يمكنك تضمين مَعلمات اختيارية، مثل allowDynamicTheme وdefaultColorScheme. القيمة التلقائية لـ allowDynamicTheme هي true، ويمثّل defaultColorScheme ColorScheme المستخدَم عندما لا تتوفّر الألوان الديناميكية، مثلاً عندما أوقف المستخدم الميزة أو عندما لا يكون الجهاز متوافقًا معها أو عندما تكون قيمة allowDynamicTheme هي false.

  2. إنشاء واجهة المستخدم ضمن النطاق: يجب تحديد جميع مكوّنات واجهة المستخدم لتصميم Tile معيّن ضمن lambda لاستدعاء 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(text = "Action".layoutString) }
        )
    }
    

ألعاب المقامرة

في 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(): زر على شكل حبّة دواء يوفّر ما يصل إلى ثلاث خانات لعرض محتوى يمثّل تصنيفًا وتصنيفًا ثانويًا مكدّسَين عموديًا، ورمزًا بجانبهما

أزرار الحافة

زر الحافة هو زر مخصّص بعرض كامل ومثبّت في أسفل شاشة الساعة الدائرية، ويمثّل أهم إجراء يمكن اتخاذه من شاشة المربّع الحالية.

  • iconEdgeButton(): زر على الحافة يوفّر خانة واحدة لعرض رمز أو محتوى صغير دائري مشابه
  • textEdgeButton(): زر على الحافة يوفّر موضعًا إعلانيًا واحدًا لعرض نص أو محتوى طويل وعريض بالمثل

بيانات بطاقات الائتمان

تكون البطاقات مخصّصة بشكل أساسي لتقديم المعلومات. وهي تعرض مجموعات من البيانات المنظَّمة ذات الصلة. على الرغم من أنّه يمكنك إنشاء بطاقات تفاعلية، إلا أنّها تعرض عادةً ملخّصًا للمعلومات، ويمكن للمستخدم بعد ذلك النقر عليها للاطّلاع على المزيد من التفاصيل أو تنفيذ إجراء ذي صلة.

  • titleCard(): بطاقة العنوان التي توفّر من خانة إلى ثلاث خانات، وعادةً ما تكون مستندة إلى النص
  • appCard(): بطاقة التطبيق التي توفّر ما يصل إلى خمس مساحات إعلانية، وعادةً ما تكون مستندة إلى النصوص
  • textDataCard(): بطاقة بيانات توفّر ما يصل إلى ثلاث خانات مكدّسة عموديًا، وعادةً ما تكون مستندة إلى نصوص أو أرقام
  • iconDataCard(): بطاقة بيانات توفّر ما يصل إلى ثلاث خانات مكدّسة عموديًا، وعادةً ما تكون مستندة إلى نصوص أو أرقام، مع رمز
  • graphicDataCard(): بطاقة بيانات رسومية توفّر خانة للبيانات الرسومية، مثل مؤشر التقدم، وما يصل إلى خانتَين مكدّستَين عموديًا، وعادةً ما تكون مخصّصة للأوصاف النصية

مؤشرات التقدم

تجميع عناصر التصميم

  • buttonGroup(): تخطيط مكوّن يضع عناصره الثانوية في تسلسل أفقي
  • primaryLayout(): تنسيق ملء الشاشة الذي يمثّل نمط تنسيق مقترَحًا من M3 سريع الاستجابة ويتولّى تحديد موضع العناصر، بالإضافة إلى الهوامش والحشو المقترَحة

التصميم

في نظام الألوان Expressive في Material 3، يتم تحديد نظام الألوان من خلال 29 دورًا للألوان الأساسية، ويتم تنظيمها في ست مجموعات: أساسي وثانوي وثالث وخطأ وسطح ومخطّط تفصيلي.

نظام الألوان Expressive في Material 3
الشكل 3. نظام ألوان Material 3 Expressive

تحدّد ColorScheme لكل دور من هذه الأدوار الـ 29 لونًا مطابقًا، وبما أنّها جزء من MaterialScope ويجب إنشاء المكوّنات ضمنها، فإنّها تستخدم الألوان تلقائيًا من المخطّط. تتيح هذه الطريقة لجميع عناصر واجهة المستخدم الالتزام تلقائيًا بمعايير Material Design.

للسماح للمستخدمين بالاختيار بين نظام ألوان تحدّده أنت، مثل نظام يعكس ألوان علامتك التجارية، ونظام يوفّره الجهاز، سواء كان مستمدًا من خلفية شاشة الساعة الحالية للمستخدم أو اختاره المستخدم، عليك تهيئة MaterialScope على النحو التالي:

val myColorScheme =
    ColorScheme(
        primary = ...
        onPrimary = ...
        // 27 more
    )

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

لفرض ظهور المربّعات بالألوان التي تحدّدها، عليك إيقاف ميزة &quot;السمات الديناميكية&quot; من خلال ضبط قيمة allowDynamicTheme على false:

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

اللون

يستخدم كل مكوّن فردي مجموعة فرعية من أدوار الألوان الـ 29 المحدّدة بواسطة ColorScheme. على سبيل المثال، تستخدم الأزرار ما يصل إلى أربعة ألوان، يتم أخذها تلقائيًا من المجموعة "الأساسية" من ColorScheme النشط:

ButtonColors الرمز المميّز للمكوّن دور ColorScheme
containerColor أساسي
iconColor onPrimary
labelColor onPrimary
secondaryLabelColor onPrimary (مستوى التعتيم 0.8)

للحصول على إرشادات تفصيلية حول تطبيق الألوان على تصاميم Wear OS، اطّلِع على دليل تصميم الألوان.

قد تحتاج إلى الخروج عن الرموز المميزة للألوان التلقائية لعناصر معيّنة في واجهة المستخدم. على سبيل المثال، قد تريد استخدام textEdgeButton واحد لاستخدام ألوان من المجموعة "الثانوية" أو "الثالثة" بدلاً من "الأساسية"، وذلك بهدف التميّز وتحقيق تباين أفضل.

يمكنك تخصيص ألوان المكوّنات بعدّة طرق:

  1. استخدام دالة مساعدة للألوان المحدّدة مسبقًا استخدِم دوال مساعدة مثل filledTonalButtonColors() لتطبيق أنماط الأزرار العادية على Material 3 Expressive. تنشئ هذه الدوال مثيلات ButtonColors تم ضبط إعداداتها مسبقًا، وتربط الأنماط الشائعة، مثل الأنماط المعبّأة أو اللونية أو المخطّطة، بالأدوار المناسبة من 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.argb // Using a hex code for yellow
        )
        // ... other parameters
    )
    

أسلوب الخط

لمزيد من المعلومات حول استخدام أسلوب الخط بشكل فعّال في تصميماتك، يمكنك الاطّلاع على دليل تصميم أسلوب الخط.

لتحقيق اتساق مرئي على مستوى منصة Wear OS وتحسين الأداء، يتم عرض كل النص على البلاطات باستخدام خط توفّره المنصة. أي أنّ المربّعات لا تتوافق مع الخطوط المخصّصة. في الإصدار 6 من Wear OS والإصدارات الأحدث، يكون هذا الخط خاصًا بالمصنّع الأصلي للجهاز. في معظم الحالات، سيكون الخط متغيرًا، ما يوفّر تجربة أكثر تعبيرًا وتحكّمًا أكثر دقة.

لإنشاء نمط نص، يمكنك عادةً استخدام طريقة text() مع الثوابت الطباعية. يتيح لك هذا المكوّن الاستفادة من أدوار الخطوط المحدّدة مسبقًا في Material 3 Expressive، ما يساعد إعلانك على شكل مربّع على الالتزام بأفضل الممارسات المحدّدة للخطوط من أجل سهولة القراءة والتسلسل الهرمي. توفّر المكتبة مجموعة من 18 ثابتًا للدلالات المتعلقة بالكتابة، مثل BODY_MEDIUM. تؤثّر هذه الثوابت أيضًا في محاور الخطوط الأخرى غير الحجم.

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

لمزيد من التحكّم، يمكنك تقديم إعدادات إضافية. في الإصدار 6 من Wear OS والإصدارات الأحدث، من المحتمل أن يتم استخدام خط متغير يمكنك تعديله على المحاور المائل والوزن والعرض والاستدارة. يمكنك التحكّم في هذه المحاور باستخدام المَعلمة 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. تأتي القيم من السمة MaterialScope shapes:

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: تعرض خطًا منحنيًا حول Arc.
  • ArcText: لعرض نص منحني في Arc.
  • ArcAdapter: تعرض عنصر تخطيط أساسيًا في القوس، ويتم رسمه بشكل مماسي للقوس.

لمزيد من المعلومات، راجِع المستندات المرجعية لكل نوع من أنواع العناصر.

مفاتيح التعديل

يمكن اختياريًا تطبيق معدِّلات على كل عنصر من عناصر التصميم المتاحة. استخدِم مفاتيح التعديل هذه للأغراض التالية:

  • تغيير المظهر المرئي للتصميم على سبيل المثال، أضِف خلفية أو حدًا أو مساحة متروكة إلى عنصر التنسيق.
  • أضِف بيانات وصفية حول التنسيق. على سبيل المثال، أضِف معدِّلاً دلاليًا إلى عنصر التنسيق لاستخدامه مع برامج قراءة الشاشة.
  • إضافة وظائف على سبيل المثال، أضِف معدِّلاً قابلاً للنقر إلى عنصر التنسيق لجعل البطاقة تفاعلية. لمزيد من المعلومات، يُرجى الاطّلاع على مقالة التفاعل مع المربّعات.

على سبيل المثال، يمكننا تخصيص المظهر التلقائي والبيانات الوصفية الخاصة Image، كما هو موضّح في نموذج الرمز البرمجي التالي:

Kotlin

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

Java

private LayoutElement myImage() {
   return new Image.Builder()
           .setWidth(dp(24f))
           .setHeight(dp(24f))
           .setResourceId("image_id")
           .setModifiers(new Modifiers.Builder()
                   .setBackground(new Background.Builder().setColor(argb(0xFFFF0000)).build())
                   .setPadding(new Padding.Builder().setStart(dp(12f)).build())
                   .setSemantics(new Semantics.Builder()
                           .setContentDescription("Image description")
                           .build()
                   ).build()
           ).build();
}

Spannables

Spannable هي نوع خاص من الحاويات التي تعرض العناصر بطريقة مشابهة للنص. ويكون هذا مفيدًا عندما تريد تطبيق نمط مختلف على سلسلة فرعية واحدة فقط في جزء أكبر من النص، وهو أمر لا يمكن تنفيذه باستخدام العنصر Text.

حاوية Spannable مليئة بالعناصر الثانوية Span. لا يُسمح بعناصر ثانوية أخرى أو مثيلات Spannable متداخلة.

هناك نوعان من Span الأطفال:

  • SpanText: لعرض نص بنمط معيّن.
  • SpanImage: لعرض صورة مضمّنة مع النص.

على سبيل المثال، يمكنك إمالة كلمة "world" في بطاقة "Hello world" وإدراج صورة بين الكلمتين، كما هو موضّح في عينة الرمز البرمجي التالية:

Kotlin

private fun mySpannable(): LayoutElement =
    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()

Java

private LayoutElement mySpannable() {
   return new Spannable.Builder()
        .addSpan(new SpanText.Builder()
            .setText("Hello ")
            .build()
        )
        .addSpan(new SpanImage.Builder()
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .setResourceId("image_id")
            .build()
        )
        .addSpan(new SpanText.Builder()
            .setText("world")
            .setFontStyle(newFontStyle.Builder()
                .setItalic(true)
                .build())
            .build()
        ).build();
}

العمل باستخدام المراجع

لا يمكن الوصول إلى أي من موارد تطبيقك من خلال البلاطات. وهذا يعني أنّه لا يمكنك تمرير معرّف صورة Android إلى عنصر تخطيط Image وتتوقّع أن يتم حلّه. بدلاً من ذلك، يمكنك إلغاء طريقة onTileResourcesRequest() وتوفير أي موارد يدويًا.

هناك طريقتان لتوفير الصور ضمن طريقة onTileResourcesRequest():

Kotlin

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

Java

@Override
protected ListenableFuture<Resources> onTileResourcesRequest(
       @NonNull ResourcesRequest requestParams
) {
return Futures.immediateFuture(
    new Resources.Builder()
        .setVersion("1")
        .addIdToImageMapping("image_from_resource", new ImageResource.Builder()
            .setAndroidResourceByResId(new AndroidImageResourceByResId.Builder()
                .setResourceId(R.drawable.image_id)
                .build()
            ).build()
        )
        .addIdToImageMapping("image_inline", new ImageResource.Builder()
            .setInlineResource(new InlineImageResource.Builder()
                .setData(imageAsByteArray)
                .setWidthPx(48)
                .setHeightPx(48)
                .setFormat(ResourceBuilders.IMAGE_FORMAT_RGB_565)
                .build()
            ).build()
        ).build()
);
}

قائمة التحقّق من صورة معاينة المربّع

يعرض النظام صورة معاينة المربّع، المشار إليها في ملف بيان تطبيق Android، في أداة تعديل لوحة عرض المربّعات الدوّارة لإضافة مربّع جديد. يظهر هذا المحرّر على أجهزة Wear OS وفي تطبيق الساعة المصاحب على الهواتف.

لمساعدة المستخدمين على الاستفادة إلى أقصى حد من صورة المعاينة هذه، يُرجى التأكّد من صحة التفاصيل التالية حول المربّع:

  • تعكس أحدث تصميم: يجب أن تمثّل المعاينة أحدث تصميم لبطاقتك بدقة.
  • استخدام السمات المقترَحة لتقديم أفضل جودة عرض ممكنة وتجربة جيدة للمستخدم، يجب أن تبلغ أبعاد صورة المعاينة 400 بكسل × 400 بكسل.
  • يستخدم تصميمًا ثابتًا للألوان. استخدِم مظهر الألوان الثابت للّوحة، وليس مظهرًا ديناميكيًا.
  • يتضمّن رمز التطبيق تأكَّد من ظهور رمز تطبيقك في أعلى صورة المعاينة.
  • تعرض هذه السمة حالة التحميل أو تسجيل الدخول. يجب أن تعرض المعاينة حالة "تم التحميل" أو "تم تسجيل الدخول" تعمل بشكل كامل، مع تجنُّب أي محتوى فارغ أو محتوى العنصر النائب.
  • الاستفادة من قواعد حلّ الموارد للتخصيص (اختياري) ننصحك باستخدام قواعد تحليل الموارد في Android لتقديم معاينات تتطابق مع حجم شاشة الجهاز أو اللغة أو إعدادات المنطقة. ويكون هذا الإجراء مفيدًا بشكل خاص إذا كان مظهر البلاطة يختلف على الأجهزة المختلفة.