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

در دستگاه‌های 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 حداقل نسخه طرحواره رندر مورد نیاز برای رفتار آن روش را به صورت مستند نشان می دهد ( مثال ).
    • در حالی که فراخوانی روشی که به نسخه رندر بالاتری نسبت به موجود در دستگاه نیاز دارد، باعث از کار افتادن برنامه شما نمی شود، ممکن است منجر به نمایش داده نشدن محتوا یا نادیده گرفتن ویژگی شود.

مثال

override fun onTileRequest(
    requestParams: TileService.TileRequest
): ListenableFuture<Tile> {
    val rendererVersion =
        requestParams.deviceConfiguration.rendererSchemaVersion
    val tile = Tile.Builder()

    if (
        rendererVersion.major > 1 ||
            (rendererVersion.major == 1 && rendererVersion.minor >= 300)
    ) {
        // Use a feature supported in renderer version 1.300 or later
        tile.setTileTimeline(/* ... */ )
    } else {
        // Provide fallback content for older renderers
        tile.setTileTimeline(/* ... */ )
    }

    return Futures.immediateFuture(tile.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 (مثل اطلاعات تکمیلی eection) هستند. این طرح توسط تابع 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. حذف سازندگان . الگوی سازنده سنتی برای مؤلفه‌های Material3 UI با یک نحو الهام‌گرفته از Compose با بیانی‌تر جایگزین شده است. (مولفه‌های غیر UI مانند String/Color/Modifiers نیز پوشش‌های جدید Kotlin دریافت می‌کنند.)
  2. توابع اولیه سازی و طرح بندی استاندارد شده طرح‌بندی‌های M3 بر توابع اولیه و ساختار استاندارد شده تکیه می‌کنند: materialScope() و primaryLayout() . این توابع اجباری محیط M3 را مقداردهی اولیه می‌کنند (مضمون‌سازی، دامنه مؤلفه از طریق materialScope ) و طرح‌بندی مبتنی بر اسلات اولیه را تعریف می‌کنند (از طریق primaryLayout ). هر دو باید دقیقاً یک بار در هر چیدمان فراخوانی شوند.

موضوع بندی

رنگ

یکی از ویژگی های برجسته 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.2.1"
  implementation "androidx.wear.protolayout:protolayout-material:1.2.1"
  implementation "androidx.wear.protolayout:protolayout-expression:1.2.1"

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

کاتلین

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

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

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

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

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