Materyal Tasarım 2

Jetpack Compose, dijital arayüzler oluşturmak için kapsamlı bir tasarım sistemi olan Materyal Tasarım'ı kullanır. Materyal Tasarım bileşenleri (düğmeler, kartlar, anahtarlar vb.), Materyal Tema'ın üzerine inşa edilmiştir. Malzeme Tasarımı, ürününüzün markasını daha iyi yansıtacak şekilde sistematik bir şekilde kişiselleştirilebilir. Materyal Tema, renk, yazı tipi ve şekil özelliklerini içerir. Bu özellikleri özelleştirdiğinizde, yaptığınız değişiklikler uygulamanızı derlemek için kullandığınız bileşenlere otomatik olarak yansıtılır.

Jetpack Compose, bu kavramları oluşturabileceğiniz MaterialTheme ile uygular:

MaterialTheme(
    colors = // ...
    typography = // ...
    shapes = // ...
) {
    // app content
}

Uygulamanıza tema eklemek için MaterialTheme öğesine ilettiğiniz parametreleri yapılandırın.

Birbiriyle zıt içerikli iki ekran görüntüsü. İlki varsayılan MaterialTheme stilini kullanırken,
ikinci ekran görüntüsünde değiştirilmiş stil kullanılır.

Şekil 1. İlk ekran görüntüsünde MaterialTheme yapılandırmadığı için varsayılan stil kullanılan bir uygulama gösterilmektedir. İkinci ekran görüntüsünde, stili özelleştirmek için parametreleri MaterialTheme öğesine geçiren bir uygulama gösterilmektedir.

Renk

Renkler, Compose'da basit bir veri tutma sınıfı olan Color sınıfıyla modellenir.

val Red = Color(0xffff0000)
val Blue = Color(red = 0f, green = 0f, blue = 1f)

Bunları istediğiniz gibi düzenleyebilirsiniz (üst düzey sabit değerler, tekli içinde veya tanımlanmış satır içi olarak), temanızda renkleri belirtmenizi ve renkleri oradan almanızı kesinlikle öneririz. Bu yaklaşım, koyu temanın ve iç içe yerleştirilmiş temaların kolayca desteklenmesini mümkün kılar.

Temanın renk paleti örneği

2. Şekil. Malzeme renk sistemi.

Compose, Malzeme renk sistemini modellemek için Colors sınıfını sağlar. Colors, açık veya koyu renk grupları oluşturmak için oluşturucu işlevleri sağlar:

private val Yellow200 = Color(0xffffeb46)
private val Blue200 = Color(0xff91a4fc)
// ...

private val DarkColors = darkColors(
    primary = Yellow200,
    secondary = Blue200,
    // ...
)
private val LightColors = lightColors(
    primary = Yellow500,
    primaryVariant = Yellow400,
    secondary = Blue700,
    // ...
)

Colors öğenizi tanımladıktan sonra MaterialTheme adlı CSS'ye iletebilirsiniz:

MaterialTheme(
    colors = if (darkTheme) DarkColors else LightColors
) {
    // app content
}

Tema renklerini kullanma

MaterialTheme için sağlanan Colors öğesini, MaterialTheme.colors kullanarak oluşturabilirsiniz.

Text(
    text = "Hello theming",
    color = MaterialTheme.colors.primary
)

Yüzey ve içerik rengi

Birçok bileşen bir çift rengi ve içerik rengini kabul eder:

Surface(
    color = MaterialTheme.colors.surface,
    contentColor = contentColorFor(color),
    // ...
) { /* ... */ }

TopAppBar(
    backgroundColor = MaterialTheme.colors.primarySurface,
    contentColor = contentColorFor(backgroundColor),
    // ...
) { /* ... */ }

Bu şekilde, yalnızca oluşturulan bir içeriğin rengini ayarlamakla kalmaz,aynı zamanda içerik (içerik) için de varsayılan bir renk sağlayabilirsiniz. Birçok bestede varsayılan olarak bu içerik rengi kullanılır. Örneğin, Text, rengini üst öğesinin içerik rengine dayandırır ve Icon, tonunu ayarlamak için bu rengi kullanır.

Farklı renklere sahip aynı banner'ın iki örneği

3. Şekil. Farklı arka plan renkleri ayarlamak, farklı metinler ve simge renkleri oluşturur.

contentColorFor() yöntemi, tüm tema renkleri için uygun "on" rengini alır. Örneğin, Surface üzerinde bir primary arka plan rengi ayarlarsanız bu işlev, içerik rengi olarak onPrimary değerini ayarlamak için kullanılır. Tema dışı bir arka plan rengi ayarlarsanız uygun bir içerik rengi de belirtmeniz gerekir. Hiyerarşide belirli bir konumda, geçerli arka plan için tercih edilen içerik rengini almak amacıyla LocalContentColor özelliğini kullanın.

İçerik alfa

Genellikle, önem vermek ve görsel hiyerarşi sağlamak için içeriği ne kadar vurguladığınızı değiştirmek istersiniz. Materyal Tasarım'daki metinlerin okunabilirliği önerileri, farklı önem düzeylerini iletmek için farklı opaklık düzeylerinin kullanılmasını önerir.

Jetpack Compose bunu LocalContentAlpha aracılığıyla uygular. Bu CompositionLocal için bir değer sağlayarak bir hiyerarşi için içerik alfa belirtebilirsiniz. İç içe yerleştirilmiş besteler, içeriklerine alfa işlemini uygulamak için bu değeri kullanabilir. Örneğin, Text ve Icon varsayılan olarak LocalContentAlpha kullanacak şekilde ayarlanmış LocalContentColor kombinasyonunu kullanır. Materyal, ContentAlpha nesnesi tarafından modellenen bazı standart alfa değerleri (high, medium, disabled) belirtir.

// By default, both Icon & Text use the combination of LocalContentColor &
// LocalContentAlpha. De-emphasize content by setting content alpha
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
    Text(
        // ...
    )
}
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
    Icon(
        // ...
    )
    Text(
        // ...
    )
}

CompositionLocal hakkında daha fazla bilgi edinmek için CompositionLocal ile yerel kapsamlı veriler rehberine göz atın.

Farklı düzeylerde metin vurgusunu gösteren bir makale
başlığının ekran görüntüsü

4. Şekil. Bilgi hiyerarşisini görsel olarak iletmek için metne farklı vurgu düzeyleri uygulayın. Metnin ilk satırı başlıktır ve en önemli bilgileri içerir. Bu nedenle ContentAlpha.high ifadesini kullanır. İkinci satır, daha az önemli meta veriler içerdiği için ContentAlpha.medium değerini kullanır.

Koyu tema

Compose'da, oluşturulan MaterialTheme için farklı Colors grupları sağlayarak açık ve koyu temaları uygularsınız:

@Composable
fun MyTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {
    MaterialTheme(
        colors = if (darkTheme) DarkColors else LightColors,
        /*...*/
        content = content
    )
}

Bu örnekte MaterialTheme, koyu temanın kullanılıp kullanılmayacağını belirten bir parametreyi kabul eden kendi oluşturulabilecek işlevine sarmalanmıştır. Bu durumda işlev, cihaz teması ayarını sorgulayarak darkTheme için varsayılan değeri alır.

Mevcut Colors cihazının açık mı yoksa koyu mu olduğunu kontrol etmek için aşağıdaki gibi bir kod kullanabilirsiniz:

val isLightTheme = MaterialTheme.colors.isLight
Icon(
    painterResource(
        id = if (isLightTheme) {
            R.drawable.ic_sun_24
        } else {
            R.drawable.ic_moon_24
        }
    ),
    contentDescription = "Theme"
)

Yükseklik yer paylaşımları

Malzeme öğesinde, daha yüksek yükseklikteki koyu temalara sahip yüzeylerin arka planı aydınlatılan yükseklik yer paylaşımları alır. Bir yüzeyin yüksekliği ne kadar yüksek olursa (ima edilen ışık kaynağına yaklaştırılırsa) yüzey de o kadar açık olur.

Bu bindirmeler, koyu renkler kullanıldığında Surface oluşturma özelliği ve yüzey kullanan diğer Malzemelere otomatik olarak uygulanır:

Surface(
    elevation = 2.dp,
    color = MaterialTheme.colors.surface, // color will be adjusted for elevation
    /*...*/
) { /*...*/ }

Farklı yükseklik seviyelerindeki öğeler için kullanılan biraz farklı renklerin gösterildiği bir uygulama ekran görüntüsü

5.Şekil Hem kartlarda hem de alt gezinme kartlarında arka plan olarak surface rengi kullanılıyor. Kartlar ve alt gezinme kartları, arka planın üzerinde farklı yükseklik düzeylerinde yer aldığından biraz farklı renklere sahiptir: Kartlar arka plandan daha açık, alt gezinme menüsü ise kartlardan daha hafiftir.

Surface içermeyen özel senaryolar için LocalElevationOverlay veya Surface bileşenleri tarafından kullanılan ElevationOverlay öğesini içeren CompositionLocal kullanın:

// Elevation overlays
// Implemented in Surface (and any components that use it)
val color = MaterialTheme.colors.surface
val elevation = 4.dp
val overlaidColor = LocalElevationOverlay.current?.apply(
    color, elevation
)

Yükseklik yer paylaşımlarını devre dışı bırakmak için, oluşturulabilir bir hiyerarşide istediğiniz noktada null sağlayın:

MyTheme {
    CompositionLocalProvider(LocalElevationOverlay provides null) {
        // Content without elevation overlays
    }
}

Sınırlı renk vurguları

Materyal, çoğu durumda primary rengi yerine surface rengini tercih ederek koyu temalar için sınırlı renk vurguları uygulanmasını önerir. TopAppBar ve BottomNavigation gibi malzeme besteleri bu davranışı varsayılan olarak uygular.

6.Şekil Sınırlı renk vurgularına sahip koyu renkli malzeme teması. Üst uygulama çubuğu, açık temada birincil rengi, koyu temada yüzey rengi kullanır.

Özel senaryolar için primarySurface uzantı özelliğini kullanın:

Surface(
    // Switches between primary in light theme and surface in dark theme
    color = MaterialTheme.colors.primarySurface,
    /*...*/
) { /*...*/ }

Yazı biçimi

Materyal, bir tür sistemi tanımlayarak sizi anlamsal olarak adlandırılmış az sayıda stil kullanmaya teşvik eder.

Çeşitli stillerde farklı yazı tipleri örneği

7. Şekil. Materyal türü sistemi.

Oluşturma işlemi, tür sistemini Typography, TextStyle ve yazı tipiyle ilgili sınıflarıyla uygular. Typography oluşturucu, her stil için varsayılanlar sunar. Böylece özelleştirmek istemediklerinizi çıkarabilirsiniz:

val raleway = FontFamily(
    Font(R.font.raleway_regular),
    Font(R.font.raleway_medium, FontWeight.W500),
    Font(R.font.raleway_semibold, FontWeight.SemiBold)
)

val myTypography = Typography(
    h1 = TextStyle(
        fontFamily = raleway,
        fontWeight = FontWeight.W300,
        fontSize = 96.sp
    ),
    body1 = TextStyle(
        fontFamily = raleway,
        fontWeight = FontWeight.W600,
        fontSize = 16.sp
    )
    /*...*/
)
MaterialTheme(typography = myTypography, /*...*/) {
    /*...*/
}

Metnin tamamında aynı yazı tipini kullanmak istiyorsanız defaultFontFamily parameter özelliğini belirtin ve TextStyle öğelerinin fontFamily kısmını çıkarın:

val typography = Typography(defaultFontFamily = raleway)
MaterialTheme(typography = typography, /*...*/) {
    /*...*/
}

Metin stillerini kullanma

TextStyle'lere MaterialTheme.typography üzerinden erişiliyor. TextStyle öğelerini şu şekilde alın:

Text(
    text = "Subtitle2 styled",
    style = MaterialTheme.typography.subtitle2
)

Farklı amaçlar için farklı yazı tiplerinin karışımını gösteren ekran görüntüsü

Şekil 8. Markanızı ifade etmek için bir dizi yazı tipi ve stili kullanın.

Şekil

Malzeme bir şekil sistemini tanımlayarak büyük, orta ve küçük bileşenler için şekiller tanımlamanıza olanak tanır.

Çeşitli Materyal Tasarım şekilleri gösterir

Şekil 9. Malzeme şekil sistemi.

Oluşturma işlemi, şekil sistemini Shapes sınıfıyla uygular. Bu sınıf, her boyut kategorisi için bir CornerBasedShape belirtmenize olanak tanır:

val shapes = Shapes(
    small = RoundedCornerShape(percent = 50),
    medium = RoundedCornerShape(0f),
    large = CutCornerShape(
        topStart = 16.dp,
        topEnd = 0.dp,
        bottomEnd = 0.dp,
        bottomStart = 16.dp
    )
)

MaterialTheme(shapes = shapes, /*...*/) {
    /*...*/
}

Birçok bileşen varsayılan olarak bu şekilleri kullanır. Örneğin, Button, TextField ve FloatingActionButton varsayılan olarak küçük, AlertDialog varsayılan olarak orta, ModalDrawer varsayılan olarak büyüktür. Eşlemenin tamamı için şekil şeması referansına bakın.

Şekilleri kullanma

Shape'lere MaterialTheme.shapes üzerinden erişiliyor. Shape öğelerini aşağıdaki gibi bir kodla alın:

Surface(
    shape = MaterialTheme.shapes.medium, /*...*/
) {
    /*...*/
}

Bir öğenin nasıl olduğunu bildirmek için Materyal şekillerini kullanan bir uygulamanın ekran görüntüsü

Şekil 10. Markayı veya durumu ifade etmek için şekilleri kullanın.

Varsayılan stiller

Android Görünümlerindeki varsayılan stillerden oluşturma işleminde eşdeğer bir kavram yoktur. Materyal bileşenlerini sarmalayan kendi "aşırı yükleme" derlenebilir işlevlerinizi oluşturarak benzer işlevleri sağlayabilirsiniz. Örneğin, bir düğme stili oluşturmak için bir düğmeyi kendi oluşturulabilir işlevinizde sarmalayın, değiştirmek istediğiniz parametreleri doğrudan ayarlayın ve diğerlerini parametre olarak içeren composable öğesinin içinde gösterin.

@Composable
fun MyButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Button(
        colors = ButtonDefaults.buttonColors(
            backgroundColor = MaterialTheme.colors.secondary
        ),
        onClick = onClick,
        modifier = modifier,
        content = content
    )
}

Tema yer paylaşımları

MaterialTheme kompozit öğelerini iç içe yerleştirerek Compose'da Android Görünümleri'ndeki tema yer paylaşımlarına eşdeğer bir sonuç elde edebilirsiniz. MaterialTheme renk, yazı ve şekilleri varsayılan olarak geçerli tema değerine ayarlar. Bu nedenle, bir tema bu parametrelerden yalnızca birini ayarlarsa diğer parametrelerin varsayılan değerleri korunur.

Ayrıca, Görüntülemeye dayalı ekranları Oluşturma'ya taşırken android:theme özelliğinin kullanımına dikkat edin. Oluşturma kullanıcı arayüzü ağacının ilgili bölümünde yeni bir MaterialTheme kullanmanız gerekebilir.

Baykuş örneğinde, ayrıntılar ekranı ekranın büyük bölümü için bir PinkTheme, ardından ilgili bölüm için bir BlueTheme kullanır. Aşağıdaki ekran görüntüsüne ve koda bakın.

Şekil 11. Baykuş örneğinde iç içe yerleştirilmiş temalar.

@Composable
fun DetailsScreen(/* ... */) {
    PinkTheme {
        // other content
        RelatedSection()
    }
}

@Composable
fun RelatedSection(/* ... */) {
    BlueTheme {
        // content
    }
}

Bileşen durumları

Etkileşimde bulunulabilen (tıklanmış, açılıp kapatılabilir vb.) malzeme bileşenlerinin farklı görsel durumları olabilir. Durumlar şunlardır: etkin, devre dışı, basıldı vb.

Oluşturulabilir öğeler genellikle bir enabled parametresine sahiptir. false olarak ayarlamak etkileşimi engeller ve bileşen durumunu görsel olarak iletmek için renk ve yükseklik gibi özellikleri değiştirir.

Şekil 12. enabled = true (sol) ve enabled = false (sağ) içeren düğme.

Çoğu durumda, renk ve yükseklik gibi değerler için varsayılan değerleri kullanabilirsiniz. Farklı durumlarda kullanılan değerleri yapılandırmak isterseniz kullanabileceğiniz sınıflar ve kolaylık işlevleri vardır. Aşağıdaki düğme örneğine bakın:

Button(
    onClick = { /* ... */ },
    enabled = true,
    // Custom colors for different states
    colors = ButtonDefaults.buttonColors(
        backgroundColor = MaterialTheme.colors.secondary,
        disabledBackgroundColor = MaterialTheme.colors.onBackground
            .copy(alpha = 0.2f)
            .compositeOver(MaterialTheme.colors.background)
        // Also contentColor and disabledContentColor
    ),
    // Custom elevation for different states
    elevation = ButtonDefaults.elevation(
        defaultElevation = 8.dp,
        disabledElevation = 2.dp,
        // Also pressedElevation
    )
) { /* ... */ }

Şekil 13. Ayarlanan renk ve yükseklik değerlerine sahip enabled = true (sol) ve enabled = false (sağ) düğmeleri.

Küçük Dalgalar

Malzeme bileşenleri, etkileşimde bulunduklarını belirtmek için dalgaları kullanır. Hiyerarşinizde MaterialTheme kullanıyorsanız clickable ve indication gibi iç değiştiriciler olarak varsayılanIndication olarak bir Ripple kullanılır.

Çoğu durumda varsayılan Ripple kullanabilirsiniz. Görünümünü yapılandırmak isterseniz renk ve alfa gibi özellikleri değiştirmek için RippleTheme aracını kullanabilirsiniz.

RippleTheme hizmetinin kapsamını genişleterek defaultRippleColor ve defaultRippleAlpha yardımcı program işlevlerinden yararlanabilirsiniz. Daha sonra LocalRippleTheme kullanarak hiyerarşinizde özel dalga temanızı sağlayabilirsiniz:

@Composable
fun MyApp() {
    MaterialTheme {
        CompositionLocalProvider(
            LocalRippleTheme provides SecondaryRippleTheme
        ) {
            // App content
        }
    }
}

@Immutable
private object SecondaryRippleTheme : RippleTheme {
    @Composable
    override fun defaultColor() = RippleTheme.defaultRippleColor(
        contentColor = MaterialTheme.colors.secondary,
        lightTheme = MaterialTheme.colors.isLight
    )

    @Composable
    override fun rippleAlpha() = RippleTheme.defaultRippleAlpha(
        contentColor = MaterialTheme.colors.secondary,
        lightTheme = MaterialTheme.colors.isLight
    )
}

alternatif_metin

Şekil 14. RippleTheme aracılığıyla sağlanan, farklı dalga değerlerine sahip düğmeler.

Daha fazla bilgi

Yazma'da Materyal Temaları oluşturma hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara bakın.

Codelab uygulamaları

Videolar