نسخه‌بندی کاشی‌ها

در دستگاه‌های Wear OS، کاشی‌ها با دو عنصر کلیدی با نسخه‌بندی مستقل پرداز می‌شوند. برای اینکه کاشی‌های برنامه‌تان در همه دستگاه‌ها به‌درستی کار کند، باید این معماری زیربنایی را درک کنید.

  • کتابخانه‌های مرتبط با کاشی Jetpack: این کتابخانه‌ها (ازجمله Wear Tiles و Wear ProtoLayout) در برنامه شما جاسازی شده‌اند و شما به‌عنوان توسعه‌دهنده نسخه‌های آن‌ها را کنترل می‌کنید. برنامه شما از این کتابخانه‌ها برای ساختن TileBuilder.Tile شیء (ساختار داده‌ای که نشان‌دهنده «کاشی» شما است) در پاسخ به فراخوانی onTileRequest() سیستم استفاده می‌کند.
  • پردازنده ProtoLayout: این عنصر سیستم مسئول پردازنده شیء Tile در نمایشگر و مدیریت تعاملات کاربر است. نسخه پردازنده توسط توسعه‌دهنده برنامه کنترل نمی‌شود و می‌تواند در دستگاه‌های مختلف، حتی دستگاه‌هایی با سخت‌افزار یکسان، متفاوت باشد.

ظاهر یا عملکرد «کاشی» می‌تواند براساس نسخه‌های کتابخانه «کاشی‌های Jetpack» برنامه شما و نسخه «پردازنده ProtoLayout» در دستگاه کاربر متفاوت باشد. برای مثال، یک دستگاه ممکن است از چرخش یا نمایش داده‌های ضربان قلب پشتیبانی کند، درحالی‌که دستگاه دیگر ممکن است از این ویژگی‌ها پشتیبانی نکند.

این سند توضیح می‌دهد که چگونه برنامه خود را با نسخه‌های مختلف کتابخانه «کاشی‌ها» و «پردازنده ProtoLayout» سازگار کنید. همچنین نحوه انتقال به نسخه‌های بالاتر کتابخانه Jetpack را توضیح می‌دهد.

سازگاری را درنظر بگیرید

برای ایجاد «کاشی» که در طیف وسیعی از دستگاه‌ها به‌درستی کار کند، پشتیبانی از ویژگی‌های مختلف را درنظر بگیرید. این کار را می‌توانید ازطریق دو استراتژی اصلی انجام دهید: تشخیص قابلیت‌های پردازنده در زمان اجرا و ارائه جایگزین‌های داخلی.

قابلیت‌های رندرکننده را شناسایی کنید

می‌توانید چیدمان کاشی‌تان را به‌صورت پویا براساس ویژگی‌های دردسترس در دستگاهی خاص تغییر دهید.

نسخه رندرکننده را شناسایی کنید

  • از روش getRendererSchemaVersion() شیء DeviceParameters منتقل‌شده به روش onTileRequest() استفاده کنید. این روش شماره‌های نسخه اصلی و فرعی «پردازنده ProtoLayout» را در دستگاه برمی‌گرداند.
  • سپس می‌توانید از منطق شرطی در پیاده‌سازی onTileRequest() خود استفاده کنید تا طراحی یا رفتار «کاشی» خود را براساس نسخه نسخه رندرکننده شناسایی‌شده تطبیق دهید.

گزارمان @RequiresSchemaVersion

  • گزارمان @RequiresSchemaVersion در روش‌های ProtoLayout نشان‌دهنده حداقل نسخه طرحواره پردازنده لازم برای عملکرد آن روش طبق مستندات است (مثال).
    • فراخوانی روشی که به نسخه بالاتری از پردازنده نیاز دارد و در دستگاه موجود نیست باعث خرابی برنامه نمی‌شود، اما می‌تواند منجر به نمایش داده نشدن محتوا یا نادیده گرفته شدن ویژگی شود.

نمونه‌ای از شناسایی نسخه

val rendererVersion = requestParams.deviceConfiguration.rendererSchemaVersion

val arcElement =
    // DashedArcLine has the annotation @RequiresSchemaVersion(major = 1, minor = 500)
    // and so is supported by renderer versions 1.500 and greater
    if (
        rendererVersion.major > 1 ||
        (rendererVersion.major == 1 && rendererVersion.minor >= 500)
    ) {
        // Use DashedArcLine if the renderer supports it …
        DashedArcLine.Builder()
            .setLength(degrees(270f))
            .setThickness(8f)
            .setLinePattern(
                LayoutElementBuilders.DashedLinePattern.Builder()
                    .setGapSize(8f)
                    .setGapInterval(10f)
                    .build()
            )
            .build()
    } else {
        // … otherwise use ArcLine.
        ArcLine.Builder().setLength(degrees(270f)).setThickness(dp(8f)).build()
    }

ارائه کردن جایگزین‌ها

برخی‌از منابع به شما امکان می‌دهند جایگزین را مستقیماً در سازنده تعریف کنید. این روش اغلب ساده‌تر از بررسی نسخه پردازنده است و درصورت دردسترس بودن، روش ترجیحی است.

یک مورد استفاده رایج ارائه یک تصویر ثابت به‌عنوان جایگزین برای یک پویانمایی Lottie است. اگر دستگاه از پویانمایی‌های Lottie پشتیبانی نکند، به‌جای آن تصویر ثابت را پرداز می‌کند.

val lottieImage =
    ResourceBuilders.ImageResource.Builder()
        .setAndroidLottieResourceByResId(
            ResourceBuilders.AndroidLottieResourceByResId.Builder(R.raw.lottie)
                .setStartTrigger(createOnVisibleTrigger())
                .build()
        )
        // Fallback if lottie is not supported
        .setAndroidResourceByResId(
            ResourceBuilders.AndroidImageResourceByResId.Builder()
                .setResourceId(R.drawable.lottie_fallback)
                .build()
        )
        .build()

با نسخه‌های مختلف رندرکننده آزمایش کنید

برای آزمایش کردن کاشی‌هایتان دربرابر نسخه‌های مختلف رندرکننده، آن‌ها را در نسخه‌های مختلف شبیه‌ساز Wear OS مستقر کنید. (در دستگاه‌های فیزیکی، به‌روزرسانی‌های ProtoLayout Renderer ازطریق «فروشگاه Play» یا به‌روزرسانی‌های سیستم ارائه می‌شود. نمی‌توانید نسخه خاصی از رندرکننده را مجبور به نصب کنید.)

ویژگی «پیش‌نمایش کاشی» در Android Studio از یک رندرکننده جاسازی‌شده در کتابخانه Jetpack ProtoLayout که کد شما به آن وابسته است استفاده می‌کند، بنابراین رویکرد دیگر این است که هنگام آزمایش کاشی‌ها به نسخه‌های مختلف کتابخانه Jetpack وابسته باشید.

انتقال به Tiles 1.5 / ProtoLayout 1.3 (Material 3 Expressive)

کتابخانه‌های کاشی Jetpack را به‌روز کنید تا از جدیدترین بهبودها بهره‌مند شوید، ازجمله تغییرات میانای کاربری برای یکپارچه‌سازی بی‌نقص «کاشی‌ها» با سیستم.

‫Jetpack Tiles 1.5 و Jetpack ProtoLayout 1.3 چندین بهبود و تغییر قابل‌توجه را معرفی می‌کنند. این موارد عبارت‌اند از:

  • میانای برنامه‌سازی کاربردی شبیه «نوشتن» برای توصیف واسط کاربر.
  • عناصر Material 3 Expressive، ازجمله دکمه لبه پایین و پشتیبانی از تصاویر بهبودیافته: پویانمایی‌های Lottie، انواع گرادیان بیشتر، و سبک‌های خط کمانی جدید. - توجه: برخی‌از این ویژگی‌ها را می‌توان بدون انتقال به «میانای برنامه‌سازی کاربردی» جدید نیز استفاده کرد.

توصیه‌ها

هنگام انتقال کاشی‌ها، این توصیه‌ها را دنبال کنید:

  • همه کاشی‌هایتان را به‌طور هم‌زمان انتقال دهید. از ترکیب کردن نسخه‌های کاشی در برنامه‌تان خودداری کنید. اگرچه عناصر Material 3 در آرتیفکت جداگانه‌ای قرار دارند (androidx.wear.protolayout:protolayout-material3) و ازنظر فنی امکان استفاده از «کاشی‌های M2.5» و «کاشی‌های M3» در یک برنامه وجود دارد، اما ما قویاً توصیه می‌کنیم که از این رویکرد استفاده نکنید، مگر اینکه کاملاً ضروری باشد (برای مثال، اگر برنامه‌تان تعداد زیادی کاشی دارد که نمی‌توان همه آن‌ها را به‌طور هم‌زمان انتقال داد).
  • از راهنمایی‌های «تجربه کاربری کاشی‌ها» پیروی کنید. با توجه به ماهیت بسیار ساختاریافته و قالب‌بندی‌شده کاشی‌ها، از طراحی‌های موجود در نمونه‌های موجود به‌عنوان نقطه شروع برای طراحی‌های خود استفاده کنید.
  • در اندازه‌های مختلف صفحه‌نمایش و قلم آزمایش کنید. کاشی‌ها اغلب پر از اطلاعات هستند و این باعث می‌شود نوشتار (به‌ویژه وقتی روی دکمه‌ها قرار می‌گیرد) مستعد سرریز شدن و برش خوردن باشد. برای به‌حداقل رساندن این مورد، از عناصر ازپیش ساخته‌شده استفاده کنید و از سفارشی‌سازی گسترده خودداری کنید. بااستفاده از ویژگی پیش‌نمایش کاشی «استودیو Android» و همچنین در چند دستگاه واقعی آزمایش کنید.

فرایند انتقال

برای انتقال کاشی‌ها، این مراحل را دنبال کنید:

به‌روزرسانی وابستگی‌ها

ابتدا فایل build.gradle.kts را به‌روز کنید. نسخه‌ها را به‌روز کنید و وابستگی protolayout-material را به protolayout-material3 تغییر دهید، همان‌طور که نشان داده شده است:

// In build.gradle.kts

//val tilesVersion = "1.4.1"
//val protoLayoutVersion = "1.2.1"

// Use these versions for M3.
val tilesVersion = "1.5.0"
val protoLayoutVersion = "1.3.0"

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

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

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

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

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

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

‫TileService تا حد زیادی بدون تغییر باقی می‌ماند

تغییرات اصلی در این انتقال بر عناصر میانای کاربر تأثیر می‌گذارد. درنتیجه، پیاده‌سازی TileService شما، ازجمله هرگونه سازوکار بار کردن منبع، باید حداقل تغییرات را نیاز داشته باشد یا اصلاً نیازی به تغییر نداشته باشد.

استثنای اصلی مربوط به ردیابی فعالیت کاشی است: اگر برنامه شما از onTileEnterEvent() یا onTileLeaveEvent() استفاده می‌کند، توصیه می‌کنیم به onRecentInteractionEventsAsync() انتقال دهید. از API 36، این رویدادها دسته‌ای خواهند شد.

تطبیق دادن کد تولید چیدمان

در ProtoLayout 1.2 (M2.5)، روش onTileRequest() یک TileBuilders.Tile برمی‌گرداند. این شیء حاوی عناصر مختلفی بود، ازجمله TimelineBuilders.Timeline که به‌نوبه خود LayoutElement توصیف‌کننده میانای کاربری کاشی را دربرمی‌گرفت.

با ProtoLayout 1.3 (M3)، اگرچه ساختار و جریان کلی داده‌ها تغییر نکرده است، اما اکنون LayoutElement بااستفاده از رویکردی الهام‌گرفته از Compose با چیدمانی مبتنی بر جایگاه‌های تعریف‌شده ساخته می‌شود که (از بالا به پایین) شامل titleSlot (اختیاری؛ معمولاً برای عنوان اصلی یا سرصفحه)، mainSlot (الزامی؛ برای محتوای اصلی)، و bottomSlot (اختیاری؛ اغلب برای کنش‌هایی مثل دکمه لبه یا اطلاعات تکمیلی مثل نوشتار کوتاه) می‌شود. این چیدمان توسط تابع primaryLayout() ساخته شده است.

چیدمان کاشی که mainSlot،‏ titleSlot،‏ bottomSlot را نشان می‌دهد
شکل ۱.: جایگاه‌های کاشی.
مقایسه عملکردهای چیدمان M2.5 و M3

M2.5

fun myLayout(
    context: Context,
    deviceConfiguration: DeviceParametersBuilders.DeviceParameters
) =
    PrimaryLayout.Builder(deviceConfiguration)
        .setResponsiveContentInsetEnabled(true)
        .setContent(
            Text.Builder(context, "Hello World!")
                .setTypography(Typography.TYPOGRAPHY_BODY1)
                .build()
        )
        .build()

M3

fun myLayout(
    context: Context,
    deviceConfiguration: DeviceParametersBuilders.DeviceParameters,
) =
    materialScope(context, deviceConfiguration) {
        primaryLayout(mainSlot = { text("Hello, World!".layoutString) })
    }

برای برجسته کردن تفاوت‌های کلیدی:

  1. حذف سازندگان. الگوی سازنده قبلی برای عناصر UI «ماتریال» با دستور زبان الهام‌گرفته از Compose جایگزین شده است که بیشتر اعلانی است. (عناصر غیرواسط کاربر مثل «رشته/رنگ/اصلاح‌کننده‌ها» نیز پوشش‌های جدید Kotlin دریافت می‌کنند.)
  2. توابع استانداردشده برای مقداردهی اولیه و چیدمان. چیدمان‌های M3 به توابع استانداردسازی‌شده ساختار و مقداردهی اولیه متکی هستند: materialScope() و primaryLayout(). این توابع اجباری محیط M3 را راه‌اندازی می‌کنند (پوسته، محدوده عنصر بااستفاده از materialScope) و چیدمان اصلی مبتنی بر جایگاه را تعریف می‌کنند (بااستفاده از primaryLayout). هر دو باید دقیقاً یک‌بار در هر چیدمان فراخوانی شوند.

سفارشی‌سازی زمینه

«طراحی مواد ۳» چندین تغییر در زمینه‌سازی ایجاد می‌کند، ازجمله رنگ پویا و مجموعه گسترده‌ای از گزینه‌های حروف‌چینی و شکل.

رنگ

یکی از ویژگی‌های برجسته «بیانگر Material 3» «زمینه‌بندی پویا» است: کاشی‌هایی که این ویژگی را فعال می‌کنند (به‌طور پیش‌فرض روشن است) با زمینه ارائه‌شده توسط سیستم نمایش داده می‌شوند (دسترسی به آن به دستگاه و پیکربندی کاربر بستگی دارد).

تغییر دیگر در M3 افزایش تعداد نشان‌های رنگی است که از ۴ به ۲۹ افزایش یافته است. نشان‌های رنگ جدید را می‌توانید در کلاس ColorScheme پیدا کنید.

نویسه‌نگاری

مشابه M2.5، در M3 نیز به‌شدت به ثابت‌های اندازه قلم ازپیش تعریف‌شده تکیه می‌شود—تعیین مستقیم اندازه قلم توصیه نمی‌شود. این ثابت‌ها در کلاس Typography قرار دارند و طیف کمی گسترده‌تری از گزینه‌های بیانگرتر را ارائه می‌دهند.

برای جزئیات کامل، به اسناد نویسه‌نگاری مراجعه کنید.

شکل‌ها

بیشتر عناصر M3 می‌توانند در ابعاد شکل و همچنین رنگ متفاوت باشند.

یک textButton (در mainSlot) با شکل full:

کاشی با شکل «کامل» (گوشه‌های گردتر)
شکل ۲.: کاشی با شکل «کامل»

همان textButton با شکل small:

کاشی با شکل «کوچک» (گوشه‌های کمتر گرد)
شکل ۳.: کاشی با شکل «کوچک»

اجزا

عناصر M3 نسبت به عناصر M2.5 انعطاف‌پذیرتر و قابل پیکربندی‌تر هستند. ‫M2.5 اغلب برای پردازش‌های دیداری متنوع به عناصر متمایزی نیاز داشت، درحالی‌که M3 اغلب از عنصر پایه تعمیم‌یافته و بسیار پیکربندی‌پذیر با پیش‌فرض‌های خوب استفاده می‌کند.

این اصل برای چیدمان ریشه نیز اعمال می‌شود. در M2.5، این مورد یا PrimaryLayout یا EdgeContentLayout بود. در M3، پس‌از اینکه یک MaterialScope سطح بالای واحد ایجاد کردید، تابع primaryLayout() را فراخوانی می‌کنید. این تابع چیدمان ریشه را مستقیماً برمی‌گرداند—به سازنده نیاز ندارد—و LayoutElements را برای چند جایگاه، مثل titleSlot،‏ mainSlot، و bottomSlot می‌پذیرد. می‌توانید این جایگاه‌ها را با عناصر رابط کاربری عینی—مثل عناصری که توسط text()، button()، یا card() برگردانده می‌شوند—یا با ساختارهای چیدمان، مثل Row یا Column از LayoutElementBuilders پر کنید.

موضوع‌ها یکی دیگر از بهبودهای کلیدی M3 است. به‌طور پیش‌فرض، عناصر میانای کاربر به‌طور خودکار از مشخصات سبک M3 پیروی می‌کنند و از زمینه‌سازی پویا پشتیبانی می‌کنند.

M2.5 M3
عناصر تعاملی
Button یا Chip
نوشتار
Text text()
نشانگرهای پیشرفت
CircularProgressIndicator circularProgressIndicator() یا segmentedCircularProgressIndicator()
چیدمان
PrimaryLayout یا EdgeContentLayout primaryLayout()
— buttonGroup()
تصاویر
— ‫icon()،‏ avatarImage() یا backgroundImage()

اصلاح‌کننده‌ها

در M3، Modifiers که برای تزئین یا افزودن به یک عنصر استفاده می‌کنید، بیشتر شبیه Compose هستند. این تغییر می‌تواند با ساخت خودکار انواع داخلی مناسب، کد تکراری را کاهش دهد. (این تغییر با استفاده از عناصر رابط کاربری M3 متعامد است؛ درصورت لزوم، می‌توانید از اصلاح‌کننده‌های سبک سازنده از ProtoLayout 1.2 با عناصر رابط کاربری M3 استفاده کنید، و بالعکس.)

M2.5

// Uses Builder-style modifier to set opacity
fun myModifier(): ModifiersBuilders.Modifiers =
    ModifiersBuilders.Modifiers.Builder()
        .setOpacity(TypeBuilders.FloatProp.Builder(0.5F).build())
        .build()

M3

// Uses Compose-like modifiers to set opacity
fun myModifier(): LayoutModifier = LayoutModifier.opacity(0.5F)

می‌توانید اصلاح‌کننده‌ها را بااستفاده از سبک API بسازید و همچنین می‌توانید از تابع افزونه toProtoLayoutModifiers() برای تبدیل LayoutModifier به ModifiersBuilders.Modifier استفاده کنید.

توابع کمکی

درحالی‌که ProtoLayout 1.3 به بسیاری از عناصر رابط کاربری اجازه می‌دهد بااستفاده از میانای برنامه کاربردی الهام‌گرفته از Compose بیان شوند، عناصر چیدمان بنیادی مثل ردیف‌ها و ستون‌ها از LayoutElementBuilders همچنان از الگوی سازنده استفاده می‌کنند. برای پر کردن این شکاف سبکی و ترویج سازگاری با M3 جدید API مؤلفه، از توابع کمکی استفاده کنید.

بدون دستیار

primaryLayout(
    mainSlot = {
        Column.Builder()
            .setWidth(expand())
            .setHeight(expand())
            .addContent(text("A".layoutString))
            .addContent(text("B".layoutString))
            .addContent(text("C".layoutString))
            .build()
    }
)

با کمک‌رسان‌ها

// Function literal with receiver helper function
fun column(builder: Column.Builder.() -> Unit) =
    Column.Builder().apply(builder).build()

primaryLayout(
    mainSlot = {
        column {
            setWidth(expand())
            setHeight(expand())
            addContent(text("A".layoutString))
            addContent(text("B".layoutString))
            addContent(text("C".layoutString))
        }
    }
)

انتقال به Tiles 1.2 / ProtoLayout 1.0

از نسخه ۱.۲، اکثر «میاناهای برنامه‌سازی کاربردی» چیدمان «کاشی‌ها» در androidx.wear.protolayout فضای نام قرار دارند. برای استفاده از جدیدترین «میاناهای برنامه‌سازی کاربردی»، مراحل انتقال زیر را در کدتان تکمیل کنید.

به‌روزرسانی وابستگی‌ها

در فایل ساختار واحد برنامه، تغییرات زیر را اعمال کنید:

شیک

  // Remove
  implementation 'androidx.wear.tiles:tiles-material:version'

  // Include additional dependencies
  implementation "androidx.wear.protolayout:protolayout:1.4.2"
  implementation "androidx.wear.protolayout:protolayout-material:1.4.2"
  implementation "androidx.wear.protolayout:protolayout-expression:1.4.2"

  // Update
  implementation "androidx.wear.tiles:tiles:1.6.2"

کاتلین

  // Remove
  implementation("androidx.wear.tiles:tiles-material:version")

  // Include additional dependencies
  implementation("androidx.wear.protolayout:protolayout:1.4.2")
  implementation("androidx.wear.protolayout:protolayout-material:1.4.2")
  implementation("androidx.wear.protolayout:protolayout-expression:1.4.2")

  // Update
  implementation("androidx.wear.tiles:tiles:1.6.2")

به‌روزرسانی فضاهای نام

در فایل‌های کد مبتنی بر جاوا و Kotlin برنامه‌تان، به‌روزرسانی‌های زیر را انجام دهید: یا می‌توانید این نوشتار تغییر نام فضای نام را اجرا کنید.

  1. همه وارد کردن‌های androidx.wear.tiles.material.* با androidx.wear.protolayout.material.* جایگزین شود. این مرحله را برای کتابخانه androidx.wear.tiles.material.layouts نیز تکمیل کنید.
  2. بیشتر واردات androidx.wear.tiles.* دیگر را با androidx.wear.protolayout.* جایگزین کنید.

    وارد کردن برای androidx.wear.tiles.EventBuilders، androidx.wear.tiles.RequestBuilders، androidx.wear.tiles.TileBuilders، و androidx.wear.tiles.TileService باید یکسان بماند.

  3. چند روش منسوخ‌شده را از کلاس‌های TileService و TileBuilder تغییر نام دهید:

    1. ‫TileBuilders: getTimeline() تا getTileTimeline()، و setTimeline() تا setTileTimeline()
    2. ‫TileService: onResourcesRequest() تا onTileResourcesRequest()
    3. ‫RequestBuilders.TileRequest: getDeviceParameters() تا getDeviceConfiguration()، setDeviceParameters() تا setDeviceConfiguration()، getState() تا getCurrentState()، و setState() تا setCurrentState()