نسخه سازی کاشی ها

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

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

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

این سند توضیح می دهد که چگونه برنامه خود را با نسخه های مختلف کتابخانه Tiles و ProtoLayout Renderer سازگار کنید. همچنین نحوه مهاجرت به نسخه های بالاتر کتابخانه Jetpack را توضیح می دهد.

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

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

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

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

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

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

حاشیه نویسی @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 Store یا به‌روزرسانی‌های سیستم ارائه می‌شوند. نمی‌توان یک نسخه رندر خاص را مجبور کرد نصب شود.)

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

مهاجرت به Tiles 1.5 / ProtoLayout 1.3 (Material 3 Expressive)

کتابخانه‌های Jetpack Tile خود را به‌روزرسانی کنید تا از آخرین پیشرفت‌ها، از جمله تغییرات UI برای ادغام یکپارچه کاشی‌ها با سیستم، استفاده کنید.

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

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

توصیه ها

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

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

فرآیند مهاجرت

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

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

ابتدا فایل 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-rc01"
val protoLayoutVersion = "1.3.0-rc01"

 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 تا حد زیادی بدون تغییر باقی می ماند

تغییرات اولیه در این مهاجرت بر اجزای UI تأثیر می گذارد. در نتیجه، پیاده‌سازی 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 (اجباری؛ برای the buttonopt). یا اطلاعات تکمیلی مانند متن کوتاه). این طرح توسط تابع primaryLayout() ساخته شده است.

طرح بندی کاشی که شکاف اصلی، عنوان اسلات، شکاف پایین را نشان می دهد
شکل 1. : شکاف های کاشی.
مقایسه عملکردهای طرح بندی 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)
                .setColor(argb(0xFFFFFFFF.toInt()))
                .build()
        )
        .build()

M3

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

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

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

موضوع بندی

متریال 3 چندین تغییر را در قالب بندی ایجاد می کند، از جمله رنگ پویا و مجموعه گسترده ای از گزینه های تایپوگرافی و شکل.

رنگ

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

تغییر دیگر در M3 افزایش تعداد نشانه های رنگی است که از 4 به 29 افزایش یافته است. توکن های رنگی جدید را می توان در کلاس ColorScheme یافت.

تایپوگرافی

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

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

شکل

اکثر اجزای M3 می توانند در ابعاد شکل و همچنین رنگ متفاوت باشند.

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

کاشی با شکل "کامل" (گوشه های گردتر)
شکل 2. : کاشی با شکل "کامل".

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

کاشی با شکل "کوچک" (گوشه های گرد کمتر)
شکل 3. : کاشی با شکل "کوچک".

اجزاء

اجزای 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

// A Builder-style modifier to set the opacity of an element to 0.5
fun myModifier(): ModifiersBuilders.Modifiers =
    ModifiersBuilders.Modifiers.Builder()
        .setOpacity(TypeBuilders.FloatProp.Builder(0.5F).build())
        .build()

M3

// The equivalent Compose-like modifier is much simpler
fun myModifier(): LayoutModifier = LayoutModifier.opacity(0.5F)

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

توابع کمکی

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

بدون یاوران

primaryLayout(
    mainSlot = {
        LayoutElementBuilders.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 مهاجرت کنید

از نسخه 1.2، بیشتر APIهای طرح بندی کاشی ها در فضای نام androidx.wear.protolayout قرار دارند. برای استفاده از آخرین APIها، مراحل انتقال زیر را در کد خود تکمیل کنید.

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

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

شیار

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

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

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

کاتلین

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

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

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

فضاهای نام را به روز کنید

در فایل‌های کد مبتنی بر 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()