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

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

رائع

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

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

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

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

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

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

Kotlin

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

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

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

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

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

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

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

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

  • نماذج التنسيق: يمكنك تحديد الترتيب العام للعناصر المرئية على الشاشة. يستخدم المربّع نموذج تنسيق EdgeContentLayout، الذي يتضمّن مؤشر مستوى التقدّم حول حافة الشاشة، أو PrimaryLayout، الذي لا يعرض هذا المؤشر.
  • عناصر التنسيق: تمثّل عنصرًا رسوميًا فرديًا، مثل Button أو Chip، أو عدة عناصر من هذا النوع مجمّعة معًا باستخدام Column أو MultiButtonLayout أو MultiSlotLayout أو ما شابه ذلك. ويتم تضمينها في نموذج تنسيق.
  • الموارد: تتألف عناصر 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(
                        Text.Builder(this, "Hello World!")
                            .setTypography(Typography.TYPOGRAPHY_BODY1)
                            .setColor(argb(0xFFFFFFFF.toInt()))
                            .build()
                    )
                )
                .build()
        )

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

بعد ذلك، أضِف خدمة داخل علامة <application> في ملف AndroidManifest.xml.

<service
    android:name=".snippets.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>

يسجِّل فلتر الأذونات والنوايا هذه الخدمة كمقدّم مربّعات معلومات.

يظهر للمستخدم رمز المربّع وتسميته ووصفه ومصدر المعاينة عند ضبط مربّعات الشاشة على هاتفه أو ساعته.

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

الشكل 1: مربّع "مرحبًا بك"

للحصول على مثال كامل، اطّلِع على نموذج الرمز على GitHub أو codelab.

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

يتم كتابة تنسيق مربّع باستخدام نمط مصنّع. يتم تأسيس تنسيق مربّع الشاشة مثل شجرة تتألف من حاويات التنسيق وعناصر التنسيق الأساسية. يحتوي كل عنصر تنسيق على سمات يمكنك ضبطها من خلال طرق مختلفة لتحديد القيم.

عناصر التنسيق الأساسية

تتوفّر العناصر المرئية التالية من مكتبة protolayout، بالإضافة إلى مكونات التصميم المتعدد الأبعاد:

  • Text: لعرض سلسلة من النصوص مع إمكانية لفّها اختياريًا
  • Image: لعرض صورة.
  • Spacer: يقدّم مساحة بين العناصر أو يمكن أن يعمل كفاصل عند ضبط لون خلفيته.

مكوّنات التصميم المادّي

بالإضافة إلى العناصر الأساسية، توفّر مكتبة protolayout-material مكونات تضمن تصميم مربّعات معلومات يتوافق مع اقتراحات واجهة مستخدم Material Design.

  • Button: عنصر دائري قابل للنقر مصمّم ليحتوي على رمز.
  • Chip: عنصر قابل للنقر على شكل ملعب مصمّم ليحتوي على ما يصل إلى سطرين من النص ورمز اختياري.

  • CompactChip: عنصر قابل للنقر على شكل ملعب مصمّم ليحتوي على سطر من النص.

  • TitleChip: عنصر قابل للنقر على شكل ملعب مشابه لرمز Chip ولكن بارتفاع أكبر لاستيعاب نص العنوان

  • CircularProgressIndicator: مؤشر تقدم دائري يمكن وضعه داخل EdgeContentLayout لعرض مستوى التقدّم حول حواف الشاشة

حاويات التنسيق

تتوفّر الحاويات التالية، بالإضافة إلى تنسيقات Material:

  • Row: لعرض العناصر الثانوية أفقيًا، واحدة تلو الأخرى
  • Column: لعرض العناصر الثانوية عموديًا، تلو الأخرى
  • Box: تُظهر العناصر الفرعية فوق بعضها.
  • Arc: لعرض العناصر الثانوية في دائرة
  • Spannable: تُطبِّق FontStyles محدّدة على أقسام من النص بالإضافة إلى تداخل النص والصور. لمزيد من المعلومات، يُرجى الاطّلاع على العناصر التي يمكن تمديدها.

يمكن أن تحتوي كل حاوية على عنصر ثانوي واحد أو أكثر، ويمكن أن تكون هذه العناصر بدورها حاويات. على سبيل المثال، يمكن أن يحتوي Column على عناصر Row متعددة كعناصر تابعة، ما يؤدي إلى إنشاء تنسيق شبيه بالشبكة.

على سبيل المثال، يمكن أن يظهر مربّع مع تنسيق حاوية وعنصرَي تنسيق فرعيَين على النحو التالي:

Kotlin

private fun myLayout(): LayoutElement =
    Row.Builder()
        .setWidth(wrap())
        .setHeight(expand())
        .setVerticalAlignment(VERTICAL_ALIGN_BOTTOM)
        .addContent(Text.Builder()
            .setText("Hello world")
            .build()
        )
        .addContent(Image.Builder()
            .setResourceId("image_id")
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .build()
        ).build()

Java

private LayoutElement myLayout() {
    return new Row.Builder()
        .setWidth(wrap())
        .setHeight(expand())
        .setVerticalAlignment(VALIGN_BOTTOM)
        .addContent(new Text.Builder()
            .setText("Hello world")
            .build()
        )
        .addContent(new Image.Builder()
            .setResourceId("image_id")
            .setWidth(dp(24f))
            .setHeight(dp(24f))
            .build()
        ).build();
}

تنسيقات المواد

بالإضافة إلى التنسيقات الأساسية، تقدّم مكتبة protolayout-material بعض التنسيقات المميزة المصمّمة لعرض العناصر في "مَواضع" معيّنة.

  • PrimaryLayout: لعرض إجراء أساسي واحد CompactChip في أسفل الشاشة مع وضع المحتوى في منتصف الشاشة فوقه

  • MultiSlotLayout: لعرض التصنيفات الأساسية والثانوية مع محتوى اختياري بينهما وCompactChip اختياري في أسفل الصفحة

  • MultiButtonLayout: لتحديد موضع مجموعة من الأزرار مرتبة وفقًا لإرشادات Material

  • EdgeContentLayout: لتحديد موضع المحتوى حول حافة الشاشة، مثل CircularProgressIndicator عند استخدام هذا التنسيق، يتم تلقائيًا تطبيق الهوامش والوسائد المناسبة على المحتوى المضمّن فيه.

أقواس

يمكن استخدام العناصر الثانوية التالية لحاوية Arc:

  • ArcLine: لعرض خط منحني حول القوس
  • ArcText: لعرض نص منحني في شكل قوس
  • 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();
}

العناصر التي يمكن توسيع نطاقها

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

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

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

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

على سبيل المثال، يمكنك استخدام مائل على كلمة "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()
);
}