Wear OS için Compose'da kullanıcı arayüzünüzü önizleme

Android Studio Compose Önizlemeleri, Wear OS composable'larınızı farklı kol saati ekran boyutlarında, yuvarlak çerçevelerde ve yazı tipi ölçeklerinde doğrudan IDE'de incelemenize ve doğrulamanıza olanak tanır. Bunun için uygulamanızı fiziksel bir kol saatine veya emülatöre dağıtmanız gerekmez.

Wear OS cihazlarda, köşeleri içeriği kırpan yuvarlak ekranlar ve TimeText ile ScrollIndicator gibi sistem katmanları ekran kenarı boyunca kıvrımlı olduğundan Wear OS için özel olarak önizleme yapılandırmak, düzen sorunlarını erken aşamada yakalamak açısından önemlidir.


Önizleme bağımlılıklarını ayarlama

Wear OS Compose önizleme ek açıklamalarını ve cihaz tanımlarını kullanmak için modülünüzün build.gradle.kts dosyasına aşağıdaki bağımlılıkları ekleyin:

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

    // 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")
}

Önizlenecek öğeleri seçme: ekranlar ve bileşenler

Önizlemeyi nasıl yapılandıracağınız, tam ekran mı yoksa izole edilmiş bir kullanıcı arayüzü bileşeni mi önizlediğinize bağlıdır.

Tam ekranları önizleme (AppScaffold + ScreenScaffold)

Bir ekranın tamamını önizlerken ekran composable'ınızı Wear cihaz önizleme ek açıklaması kullanarak her zaman hem AppScaffold hem de ScreenScaffold içine alın. Bu, yuvarlak kol saati ekranını oluşturur ve şunları sağlar:

  • TimeText, saat yüzünün üst kavisli kenarında oluşturulur.
  • ScrollIndicator simgesi sağ çerçevede görünür.
  • EdgeButton düzgün şekilde yerleştirilmiş ve alt eğride kırpılmıştır.
  • İçerik dolgusu ve dairesel ekran kırpma, gerçek kol saati donanımını doğru şekilde yansıtır.
@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 üzerinde oluşturuldu.

Small Round (192x192dp) [Küçük Yuvarlak (192x192 dp)]

WorkoutScreenPreview, WearDevices.LARGE_ROUND üzerinde oluşturuldu.

Büyük Yuvarlak (227x227 dp)

Yalıtılmış bileşenleri önizleme

Özel Card, Button veya durum çipi gibi tek tek bileşenlerin önizlemesini yaparken device parametresini atlayın ve koyu arka planlı standart bir @Preview kullanın. Bu sayede, Wear Material 3 renkleri ve kontrastı, tam dairesel saat ekranı oluşturmadan doğru şekilde görünür:

@Preview(
    showBackground = true,
    backgroundColor = 0xFF000000
)
@Composable
fun HeartRateCardPreview() {
    MaterialTheme {
        HeartRateCard(bpm = 142, zone = "Aerobic")
    }
}
Saat çerçevesi olmadan izole edilmiş HeartRateCardPreview bileşen önizlemesi

Yalıtılmış bileşen önizlemesi (cihaz çerçevesi yok).


Yerleşik çoklu önizleme ek açıklamaları

androidx.wear.compose.ui.tooling.preview paketi, koyu arka planları (backgroundColor = 0xFF000000, showBackground = true) ve yuvarlak kol saati cihazı boyutlarını otomatik olarak yapılandıran yerleşik ek açıklamalar sağlar:

Ek Açıklama Ne işe yarar? Ne zaman kullanılır?
@WearPreviewSmallRound WearDevices.SMALL_ROUND (192x192 dp) üzerinde 1 önizleme. En kısıtlı dairesel görüntü boyutunda hızlı yineleme.
@WearPreviewLargeRound WearDevices.LARGE_ROUND üzerinde 1 önizleme (227x227 dp). Daha büyük kol saatlerinde düzen yoğunluğunu ve ekstra boşluğu inceleme.
@WearPreviewDevices 2 önizleme: SMALL_ROUND ve LARGE_ROUND. Her ekran composable'ı için standart çok cihazlı kontrol.
@WearPreviewFontScales Tüm Wear yazı tipi ölçeklerinde (küçük [0.94f], normal [1.0f], orta [1.06f], büyük [1.12f], daha büyük [1.18f] ve en büyük [1.24f]) SMALL_ROUND üzerinde 6 önizleme. Metin kaydırma, üç nokta ve düğme yüksekliği genişletme kontrolü.

Kapsamlı bir test matrisi oluşturmak için @WearPreviewDevices ve @WearPreviewFontScales öğelerini aynı önizleme işlevinde birleştirebilirsiniz:

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

Özel önizleme ek açıklamaları ve donanım özellikleri

Belirli donanım boyutlarını, uzun yerelleştirilmiş dizeleri veya en kötü durum kombinasyonlarını test etmek gibi daha ayrıntılı kontrol gerektiğinde @Preview doğrudan yapılandırabilir ya da kendi özel çoklu önizleme ek açıklamalarınızı tanımlayabilirsiniz.

Kullanılabilir WearDevices sabitler ve özel donanım özellikleri

androidx.wear.tooling.preview.devices.WearDevices nesnesi, standart cihaz kimlikleri sağlar:

  • WearDevices.SMALL_ROUND ("id:wearos_small_round", 192x192dp)
  • WearDevices.LARGE_ROUND ("id:wearos_large_round", 227x227dp)

Ekstra büyük yuvarlak ekranlarda (ör. 44-45 mm'lik saatler veya 240x240 dp'lik Ultra modelleri) önizleme yapmak için spec: parametresine özel bir device dizesi iletin:

@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")
        }
    }
}

Özel çoklu önizleme notu oluşturma

Uç bir senaryoyu incelemek için en küçük yuvarlak ekranı, en büyük yazı tipi ölçeği ve ayrıntılı bir yerel ayarı (ör. Almanca) standart bir büyük yuvarlak ekranla eşleştiren özel bir çoklu önizleme açıklaması oluşturun:

@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
Standart büyük tur önizlemesi

1. Standart Büyük Yuvarlak

En büyük yazı tipi ölçeğiyle çok küçük yuvarlak

2. Extreme Small Round (Largest Font + German)


Kaydırılan sütunları önizleme (TransformingLazyColumn)

Varsayılan olarak, TransformingLazyColumn ilk öğesiyle başlatılır ve index = 0 ekranın en üstüne sabitlenir. Ancak Wear OS'te öğeler, ekranın üst ve alt kavisli kenarlarına yaklaştıkça yüksekliklerini ve yuvarlak köşelerini (SurfaceTransformation) değiştirir. EdgeButton ise yalnızca en alta kaydırıldığında görünür.

Listenin bir kısmı aşağı kaydırıldığında veya listenin en altında nasıl göründüğünü önizlemek için:

1. adım: Ekranınızda TransformingLazyColumnState öğesini oluşturun

Ekran composable'ınızın, varsayılan değer olarak rememberTransformingLazyColumnState() ile TransformingLazyColumnState parametresini kabul etmesine izin verin:

@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)
                }
            }
        }
    }
}

2. adım: initialAnchorItemIndex @Preview

rememberTransformingLazyColumnState iki isteğe bağlı ilk kaydırma parametresini kabul eder:

  • initialAnchorItemIndex: Int: Negatif olmayan bir dizine (ör. 3) ayarlandığında liste, izleme görüntü alanında ortalanmış öğeyle başlatılır.
  • initialAnchorItemScrollOffset: Int: Ortalanmış sabitleme öğesine göre isteğe bağlı piksel uzaklığı uygulanır.

Aynı ekranın üst, orta (kaydırılmış) ve alt (EdgeButton görünür) durumlarını gösteren yan yana önizlemeler oluşturabilirsiniz:

@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, listenin en üstüne sabitlendi

Üst (Varsayılan -1)

InboxScreen, orta dizin 3'e kaydırıldı

Orta (initialAnchorItemIndex = 3)

EdgeButton genişletilmiş haldeyken gelen kutusu ekranı en alta kaydırılmış

Alt (EdgeButton genişletilmiş)

İpucu: Android Studio'daki herhangi bir @Preview öğesinde Etkileşimli Modu Başlat'ı tıklayarak da TransformingLazyColumn öğesini fare veya dokunmatik yüzeyinizle canlı olarak kaydırabilir ve SurfaceTransformation şekil değiştirme, EdgeButton giriş animasyonları ve ScrollIndicator hareketini gerçek zamanlı olarak inceleyebilirsiniz.

Kaydırma sırasında Guard ScrollIndicator (LocalScrollCaptureInProgress)

Sistemde kaydırma yakalama (uzun ekran görüntüleri) veya çok çerçeveli ekran görüntüsü testi araçları, kaydırılan bir TransformingLazyColumn yakaladığında, Compose, birden fazla görüntü alanı döşemesini dikey olarak yakalayıp birleştirirken LocalScrollCaptureInProgress.current değerini true olarak ayarlar.

ScreenScaffold, kaydırma yakalama sırasında scrollIndicator öğesini otomatik olarak gizlemediğinden, kayan kaydırma çubuğu yerleşimi, !LocalScrollCaptureInProgress.current ile açıkça korumadığınız sürece uzun bir ekran görüntüsünün her birleştirilmiş kutusunda tekrarlanır:

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