Halaman ini menjelaskan praktik terbaik untuk menggunakan gaya yang mencapai konsistensi di seluruh codebase Anda, serta prinsip yang kami ikuti saat mendesain API.
Anjuran
Ikuti praktik terbaik berikut:
Anjuran: Menggunakan Gaya untuk visual dan pengubah untuk perilaku
Gunakan Styles API untuk konfigurasi visual (latar belakang, padding, batas), dan sediakan pengubah untuk perilaku seperti logika klik, deteksi gestur, atau aksesibilitas.
Anjuran: Mengekspos parameter Gaya dalam sistem desain
Untuk komponen sistem desain kustom Anda sendiri, Anda harus mengekspos objek Style setelah parameter pengubah.
@Composable fun GradientButton( modifier: Modifier = Modifier, // ✅ DO: for design system components, expose a style modifier to consumers to be able to customize the components style: Style = Style ) { // Consume the style }
Anjuran: Mengganti parameter berbasis visual dengan Gaya
Pertimbangkan untuk mengganti parameter pada composable Anda dengan satu parameter Style.
Contoh:
// Before @Composable fun OldButton(background: Color, fontColor: Color) { } // After // ✅ DO: Replace visual-based parameters with a style that includes same properties @Composable fun NewButton(style: Style = Style) { }
Anjuran: Memprioritaskan Gaya untuk animasi
Gunakan blok animate bawaan untuk gaya berbasis status dengan animasi untuk peningkatan performa dibandingkan pengubah.
Anjuran: Memanfaatkan "Last-write-wins"
Manfaatkan fakta bahwa properti style menimpa, bukan menumpuk.
Gunakan ini untuk mengganti batas atau latar belakang komponen default tanpa memerlukan beberapa parameter.
Larangan
Pola berikut tidak dianjurkan:
Larangan: Menggunakan Gaya untuk logika interaksi
Jangan mencoba menangani onClick atau deteksi gestur dalam gaya. Gaya terbatas pada konfigurasi visual berdasarkan status, sehingga tidak boleh menangani logika bisnis; sebagai gantinya, gaya hanya boleh memiliki visual yang berbeda berdasarkan status.
Larangan: Menyediakan gaya default sebagai parameter default
Parameter gaya harus selalu dideklarasikan menggunakan style: Style = Style:
@Composable fun BadButton( modifier: Modifier = Modifier, // ❌ DON'T set a default style here as a parameter style: Style = Style { background(Color.Red) } ) { }
Untuk menyertakan parameter "default", gabungkan gaya parameter masuk dengan default yang ditentukan:
@Composable fun GoodButton( modifier: Modifier = Modifier, // ✅ Do: always pass it as a Style, do not pass other defaults style: Style = Style ) { // ... val defaultStyle = Style { background(Color.Red) } // ✅ Do Combine defaults inside with incoming parameter Box(modifier = modifier.styleable(styleState, defaultStyle, style)) { // your logic } }
Larangan: Menyediakan parameter gaya ke composable berbasis tata letak
Meskipun Anda dapat memberikan gaya ke composable apa pun, composable berbasis tata letak, atau composable tingkat layar, tidak diharapkan untuk menerima gaya. Dari sudut pandang konsumen, tidak jelas apa yang akan dilakukan gaya pada tingkat ini. Gaya dirancang untuk komponen, bukan tata letak.
Larangan: Membuat gaya dalam Komposisi
CompositionLocals dibaca pada titik gaya ditentukan, bukan tempat gaya digunakan. Saat gaya benar-benar digunakan, status CompositionLocal dapat berubah, sehingga menghasilkan gaya yang tidak akurat.
// DON'T - Create styles in Composition that access composition locals in this way - this will likely lead to issues when style is used / accessed, as it would not get updated when the value changes. @Composable fun containerStyle(): Style { val background = MaterialTheme.colorScheme.background val onBackground = MaterialTheme.colorScheme.onBackground return Style { background(background) contentColor(onBackground) } } // Do: Instead, Create StyleScope extension functions for your subsystems to access themed composition Locals val StyleScope.colors: JetsnackColors get() = JetsnackTheme.LocalJetsnackTheme.currentValue.colors val StyleScope.typography: androidx.compose.material3.Typography get() = JetsnackTheme.LocalJetsnackTheme.currentValue.typography val StyleScope.shapes: Shapes get() = JetsnackTheme.LocalJetsnackTheme.currentValue.shapes // Access CompositionLocals val button = Style { background(colors.brandSecondary) shape(shapes.small) }
Anjuran: Membuat satu gaya untuk perubahan nilai subsistem
Misalnya, jika beralih antara mode gelap dan terang, kueri nilai bertema yang ada (melalui CompositionLocal) untuk mengubah Style secara dinamis:
// Do: Use CompositionLocals or themed values to create a single style val buttonStyle = Style { background(colors.brandSecondary) shape(shapes.small) }
Anjuran: Mengganti seluruh Gaya saat komponen pada dasarnya berbeda di seluruh definisi tema
Anda dapat mengganti seluruh objek gaya di tingkat tema jika tema tersebut pada dasarnya berbeda.
Misalnya, jika Anda membuat aplikasi yang memiliki tema berbeda per produk/halaman atau penawaran, dan banyak properti untuk Gaya yang berbeda, mengganti seluruh kumpulan gaya di tingkat tema dapat diterima.
// DO Switch out whole styles when many properties differ - if Product A and Product B are two white labelled apps that provide different Themes. val productBThemedButton = Style { shape(shapes.small) background(colors.brandSecondary) // other properties are fundamentally different } val productAThemedButton = Style { shape(shapes.large) background(colors.brand) // other properties are fundamentally different }