پیش‌نمایش واسط کاربر در Compose برای Wear OS

«پیش‌نمایش‌های Compose در Android Studio» به شما امکان می‌دهد عناصر ترکیبی Wear OS را در اندازه‌های مختلف صفحه‌نمایش ساعت، حاشیه‌های گرد، و مقیاس‌های قلم مستقیماً در IDE بازرسی و درستی‌سنجی کنید—بدون اینکه برنامه‌تان را در ساعت فیزیکی یا شبیه‌ساز پیاده کنید.

ازآنجایی‌که دستگاه‌های Wear OS دارای نمایشگرهای دایره‌ای هستند که گوشه‌های آن محتوا را برش می‌دهد و رونهادهای سیستم مانند TimeText و ScrollIndicator در امتداد لبه صفحه انحنا دارند، پیکربندی پیش‌نمایش‌ها به‌طور خاص برای Wear OS برای شناسایی زودهنگام مشکلات چیدمان ضروری است.


راه‌اندازی وابستگی‌های پیش‌نمایش

برای استفاده از گزارمان‌های پیش‌نمایش «نوشتن» Wear OS و تعریف‌های دستگاه، وابستگی‌های زیر را به فایل build.gradle.kts واحدتان اضافه کنید:

dependencies {
    // Provides @WearPreview* multipreview annotations
    // (such as @WearPreviewDevices and @WearPreviewFontScales)
    implementation("androidx.wear.compose:compose-ui-tooling:1.8.0-alpha01")

    // Provides WearDevices constants
    // (such as WearDevices.SMALL_ROUND and WearDevices.LARGE_ROUND)
    implementation("androidx.wear:wear-tooling-preview:1.0.0")

    // Standard Compose preview support and interactive/animation inspection
    implementation("androidx.compose.ui:ui-tooling-preview")
    debugImplementation("androidx.compose.ui:ui-tooling")
}

انتخاب کنید چه چیزی پیش‌نمایش شود: صفحه‌ها یا عناصر

نحوه پیکربندی پیش‌نمایش به این بستگی دارد که آیا درحال پیش‌نمایش تمام‌صفحه هستید یا عنصر رابط کاربری مجزا.

پیش‌نمایش تمام‌صفحه (AppScaffold + ScreenScaffold)

هنگام پیش‌نمایش کل صفحه، همیشه عنصر ترکیبی صفحه را بااستفاده از گزارمان پیش‌نمایش دستگاه Wear در هر دو AppScaffold و ScreenScaffold بپیچید. این کار نمایشگر ساعت دایره‌ای را پرداز می‌کند و تضمین می‌کند که:

  • TimeText در لبه منحنی بالای صفحه ساعت ارائه می‌شود.
  • ScrollIndicator در امتداد حاشیه سمت راست ظاهر می‌شود.
  • EdgeButton به‌درستی در موقعیت قرار گرفته و در انحنای پایین چسبانده شده است.
  • حاشیه محتوا و برش صفحه‌نمایش دایره‌ای به‌دقت سخت‌افزار ساعت واقعی را منعکس می‌کند.
@WearPreviewDevices
@Composable
fun WorkoutScreenPreview() {
    MaterialTheme {
        // AppScaffold provides the top-level TimeText overlay
        AppScaffold {
            // WorkoutScreen contains its own ScreenScaffold and content
            WorkoutScreen(
                heartRate = 142,
                elapsedTime = "12:45"
            )
        }
    }
}
‫WorkoutScreenPreview در WearDevices.SMALL_ROUND ارائه شد

گرد کوچک (۱۹۲x۱۹۲ پیکسل)

‫WorkoutScreenPreview در WearDevices.LARGE_ROUND ارائه شد

گرد بزرگ (۲۲۷×۲۲۷ پیکسل)

پیش‌نمایش عناصر مجزا

هنگام پیش‌نمایش کردن عناصر تکی—مثل Card سفارشی، Button، یا تراشه وضعیت—پارامتر device را حذف کنید و از @Preview استاندارد با پس‌زمینه تیره استفاده کنید. این کار تضمین می‌کند که رنگ‌ها و کنتراست Wear Material 3 بدون پردازش کامل نمایشگر ساعت دایره‌ای به‌درستی نمایش داده شوند:

@Preview(
    showBackground = true,
    backgroundColor = 0xFF000000
)
@Composable
fun HeartRateCardPreview() {
    MaterialTheme {
        HeartRateCard(bpm = 142, zone = "Aerobic")
    }
}
پیش‌نمایش مجزای عنصر HeartRateCardPreview بدون قاب ساعت

پیش‌نمایش عنصر مجزا (بدون قاب دستگاه).


حاشیه‌نویسی‌های پیش‌نمایش چندگانه داخلی

بسته androidx.wear.compose.ui.tooling.preview حاشیه‌نویسی‌های داخلی‌ای ارائه می‌دهد که به‌طور خودکار زمینه‌های تیره (backgroundColor = 0xFF000000،‏ showBackground = true) و ابعاد دستگاه ساعت دایره‌ای را پیکربندی می‌کند:

حاشیه‌نویسی آنچه ارائه می‌کند زمان استفاده
@WearPreviewSmallRound ‫۱ پیش‌نمایش در WearDevices.SMALL_ROUND (۱۹۲x۱۹۲ پیکسل). تکرار سریع در محدودترین اندازه نمایشگر دایره‌ای.
@WearPreviewLargeRound ‫۱ پیش‌نمایش در WearDevices.LARGE_ROUND (۲۲۷×۲۲۷ پیکسل). درحال بررسی تراکم چیدمان و فاصله اضافی در ساعت‌های بزرگ‌تر.
@WearPreviewDevices ‫۲ پیش‌نمایش: SMALL_ROUND و LARGE_ROUND. بررسی استاندارد چنددستگاهی برای هر عنصر ترکیبی صفحه.
@WearPreviewFontScales ‫۶ پیش‌نمایش در SMALL_ROUND در همه مقیاس‌های قلم Wear: کوچک (0.94f)، معمولی (1.0f)، متوسط (1.06f)، بزرگ (1.12f)، بزرگ‌تر (1.18f)، و بزرگ‌ترین (1.24f). درحال بررسی کردن پیچیدن نوشتار، حذف کردن، و ازهم باز کردن ارتفاع دکمه.

می‌توانید @WearPreviewDevices و @WearPreviewFontScales را در همان تابع پیش‌نمایش پشته کنید تا ماتریس آزمون جامعی تولید کنید:

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun MessageDetailScreenPreview() {
    MaterialTheme {
        AppScaffold {
            MessageDetailScreen(
                sender = "Alex",
                body = "Running 5 mins late!"
            )
        }
    }
}

مشخصات سخت‌افزاری و گزارمان‌های پیش‌نمایش سفارشی

وقتی به کنترل دقیق‌تری نیاز دارید—مثلاً آزمایش ابعاد سخت‌افزار خاص، رشته‌های بومی‌سازی‌شده طولانی، یا ترکیب‌های بدترین حالت—می‌توانید @Preview را مستقیماً پیکربندی کنید یا شرح‌های چندپیش‌نمایش سفارشی خودتان را تعریف کنید.

‫WearDevices ثابت و مشخصات سخت‌افزاری سفارشی دردسترس است

شیء androidx.wear.tooling.preview.devices.WearDevices شناسه‌های دستگاه استاندارد را ارائه می‌دهد:

  • ‫WearDevices.SMALL_ROUND ("id:wearos_small_round"،‏ ۱۹۲x۱۹۲ پیکسل)
  • ‫WearDevices.LARGE_ROUND‏ ("id:wearos_large_round"،‏ ۲۲۷×۲۲۷ پیکسل)

برای پیش‌نمایش در نمایشگرهای گرد بسیار بزرگ (مثل ساعت‌های ۴۴ تا ۴۵ میلی‌متری یا مدل‌های Ultra با وضوح ۲۴۰x۲۴۰dp)، رشته spec: سفارشی را به پارامتر device ارسال کنید:

@Preview(
    name = "XL Round Watch (240dp)",
    device = "spec:width=240dp,height=240dp,dpi=320,isRound=true",
    showBackground = true,
    backgroundColor = 0xFF000000
)
@Composable
fun WorkoutScreenXlPreview() {
    MaterialTheme {
        AppScaffold {
            WorkoutScreen(heartRate = 142, elapsedTime = "12:45")
        }
    }
}

ایجاد یک حاشیه‌نویسی چندپیش‌نمایش سفارشی

برای بازرسی یک سناریو افراطی، یک گزارمان چندپیش‌نمای سفارشی ایجاد کنید که کوچک‌ترین صفحه گرد را با بزرگ‌ترین مقیاس قلم و یک منطقه زبانی پرحرف (مثل آلمانی) درکنار یک صفحه گرد بزرگ استاندارد جفت کند:

@Preview(
    name = "1. Standard Large Round",
    group = "Layout extremes",
    device = WearDevices.LARGE_ROUND,
    backgroundColor = 0xFF000000,
    showBackground = true
)
@Preview(
    name = "2. Extreme Small Round (Largest Font + German)",
    group = "Layout extremes",
    device = WearDevices.SMALL_ROUND,
    fontScale = 1.24f,
    locale = "de-rDE",
    backgroundColor = 0xFF000000,
    showBackground = true
)
annotation class WearPreviewExtremes
پیش‌نمایش «گرد بزرگ استاندارد»

۱. گرد بزرگ استاندارد

گرد بسیار کوچک با بزرگ‌ترین مقیاس قلم

۲. گرد کوچک شدید (بزرگ‌ترین قلم + آلمانی)


پیش‌نمایش ستون‌های پیمایشی (TransformingLazyColumn)

به‌طور پیش‌فرض، TransformingLazyColumn با اولین عنصر خود (index = 0) که در بالای صفحه سنجاق شده است مقداردهی اولیه می‌شود. بااین‌حال، در Wear OS، وقتی عناصر به لبه‌های منحنی بالا و پایین صفحه‌نمایش نزدیک می‌شوند، ارتفاع و گوشه‌های گرد آن‌ها تغییر می‌کند (SurfaceTransformation)، و EdgeButton فقط وقتی به پایین پیمایش می‌شود ظاهر می‌شود.

برای پیش‌نمایش اینکه فهرستتان هنگام پیمایش تا نیمه یا پایین فهرست چگونه به‌نظر می‌رسد:

مرحله ۱: بالا بردن TransformingLazyColumnState در عنصر ترکیبی صفحه

به عنصر ترکیبی صفحه‌نمایش اجازه دهید پارامتری با TransformingLazyColumnState مقدار پیش‌فرض rememberTransformingLazyColumnState() بپذیرد:

@Composable
fun InboxScreen(
    messages: List<Message>,
    columnState: TransformingLazyColumnState = rememberTransformingLazyColumnState(),
) {
    val transformationSpec = rememberTransformationSpec()

    ScreenScaffold(
        scrollState = columnState,
        edgeButton = {
            EdgeButton(onClick = { /* Compose new */ }) {
                Text("New message")
            }
        }
    ) { contentPadding ->
        TransformingLazyColumn(
            state = columnState,
            contentPadding = contentPadding,
        ) {
            items(messages.size) { index ->
                Card(
                    onClick = {},
                    modifier = Modifier
                        .fillMaxWidth()
                        .transformedHeight(this, transformationSpec)
                        .minimumVerticalContentPadding(
                            CardDefaults.minimumVerticalListContentPadding
                        ),
                    transformation = SurfaceTransformation(transformationSpec),
                ) {
                    Text(messages[index].subject)
                }
            }
        }
    }
}

مرحله ۲: initialAnchorItemIndex را در @Preview خود بگذرانید

‫rememberTransformingLazyColumnState دو پارامتر اختیاری پیمایش اولیه را می‌پذیرد:

  • initialAnchorItemIndex: Int: وقتی روی شاخص غیرمنفی تنظیم شود (برای مثال، 3)، فهرست با آن مورد در مرکز نمای دید ساعت مقداردهی اولیه می‌شود.
  • initialAnchorItemScrollOffset: Int: انحراف پیکسل اختیاری نسبت‌به عنصر لنگر مرکزی اعمال شد.

می‌توانید پیش‌نمایش‌های مجاوری ایجاد کنید که وضعیت‌های بالا، وسط (پیمایش‌شده)، و پایین (EdgeButton قابل‌مشاهده) را برای دقیقاً همان صفحه نشان دهد:

@WearPreviewLargeRound
@Composable
fun InboxScreenTopPreview() {
    MaterialTheme {
        AppScaffold {
            // Default (-1): Pinned to top of list (index 0)
            InboxScreen(messages = sampleMessages)
        }
    }
}

@WearPreviewLargeRound
@Composable
fun InboxScreenScrolledMiddlePreview() {
    MaterialTheme {
        AppScaffold {
            // Centers item index 3 in the viewport, showing top/bottom item morphing
            InboxScreen(
                messages = sampleMessages,
                columnState = rememberTransformingLazyColumnState(
                    initialAnchorItemIndex = 3
                )
            )
        }
    }
}

@WearPreviewLargeRound
@Composable
fun InboxScreenBottomEdgeButtonPreview() {
    MaterialTheme {
        AppScaffold {
            // Anchors on the last item so the EdgeButton is visible at the bottom
            InboxScreen(
                messages = sampleMessages,
                columnState = rememberTransformingLazyColumnState(
                    initialAnchorItemIndex = sampleMessages.lastIndex
                )
            )
        }
    }
}
‫InboxScreen در بالای فهرست سنجاق شد

بالا (پیش‌فرض -1)

«صفحه صندوق ورودی» به نمایه میانی ۳ پیمایش شد

متوسط (initialAnchorItemIndex = 3)

«صفحه ورودی» با ازهم بازشدن «دکمه کناری» به پایین پیمایش شد

پایین (EdgeButton ازهم بازشده)

نکته: همچنین می‌توانید روی شروع حالت تعاملی در هر @Preview در Android Studio کلیک کنید تا TransformingLazyColumn را با موشواره یا صفحه لمسی پیمایش کنید و SurfaceTransformation تغییر شکل، EdgeButton پویانمایی‌های ورودی، و ScrollIndicator حرکت را در زمان واقعی بازرسی کنید.

«گارد» ScrollIndicator درحین ضبط پیمایشی (LocalScrollCaptureInProgress)

وقتی ابزارهای «ضبط پیمایشی سیستم» (نماگرفت‌های طولانی) یا آزمایش نماگرفت چندقاب یک TransformingLazyColumn پیمایشی را ضبط می‌کنند، «نوشتن» LocalScrollCaptureInProgress.current را روی true تنظیم می‌کند و چندین کاشی درگاه دید را به‌صورت عمودی ضبط و به‌هم می‌چسباند.

چون ScreenScaffold به‌طور خودکار scrollIndicator خود را درحین ضبط پیمایش پنهان نمی‌کند، رونهاد نوار پیمایش شناور در هر کاشی چسبانده‌شده نماگرفت طولانی تکرار خواهد شد، مگر اینکه آن را به‌طور صریح با !LocalScrollCaptureInProgress.current محافظت کنید:

ScreenScaffold(
    scrollState = columnState,
    scrollIndicator = {
        if (!LocalScrollCaptureInProgress.current) {
            ScrollIndicator(state = columnState)
        }
    }
) { contentPadding ->
    // TransformingLazyColumn content...
    // ...
}