Gölgeler, kullanıcı arayüzünüzü görsel olarak öne çıkarır, kullanıcılara etkileşimi gösterir ve kullanıcı işlemlerine ilişkin anında geri bildirim sağlar. Compose, uygulamanıza gölge eklemenin çeşitli yollarını sunar:
Modifier.shadow(): Materyal Tasarım yönergelerine uygun bir composable'ın arkasında yüksekliğe dayalı bir gölge oluşturur.Modifier.dropShadow(): Bir composable'ın arkasında görünen ve composable'ı yükseltilmiş gibi gösteren özelleştirilebilir bir gölge oluşturur.Modifier.innerShadow(): Bir composable'ın kenarlıkları içinde gölge oluşturarak composable'ın arkasındaki yüzeye bastırılmış gibi görünmesini sağlar.
Modifier.shadow(), temel gölgeler oluşturmak için uygundur. dropShadow() ve innerShadow() değiştiricileri ise gölge oluşturma üzerinde daha ayrıntılı kontrol ve hassasiyet sağlar.
Bu sayfada, kullanıcı etkileşimi üzerine gölgeleri animasyonlu hale getirme ve innerShadow() ile dropShadow() değiştiricilerini zincirleyerek değişen gölgeler, neomorfik gölgeler ve daha fazlasını oluşturma dahil olmak üzere bu değiştiricilerin her birinin nasıl uygulanacağı açıklanmaktadır.
Temel gölgeler oluşturma
Modifier.shadow(), Materyal Tasarım yönergelerini izleyerek yukarıdan gelen bir ışık kaynağını simüle eden temel bir gölge oluşturur. Gölge derinliği elevation değerine dayanır ve döküm gölge, composable'ın şekliyle kırpılır.
@Composable fun ElevationBasedShadow() { Box( modifier = Modifier.aspectRatio(1f).fillMaxSize(), contentAlignment = Alignment.Center ) { Box( Modifier .size(100.dp, 100.dp) .shadow(10.dp, RectangleShape) .background(Color.White) ) } }
Modifier.shadow() ile oluşturulan, yüksekliğe dayalı bir gölge.Gölge uygulama
İçeriğinizin arkasına doğru bir gölge çizmek için dropShadow() değiştiricisini kullanın. Bu, öğenin yükseltilmiş gibi görünmesini sağlar.
Aşağıdaki temel özellikleri Shadow parametresi aracılığıyla kontrol edebilirsiniz:
radius: Bulanıklığınızın yumuşaklığını ve dağılımını tanımlar.color: Tonlamanın rengini tanımlar.offset: Gölgenin geometrisini x ve y eksenleri boyunca konumlandırır.spread: Gölgenin geometrisinin genişlemesini veya daralmasını kontrol eder.
Ayrıca, shape parametresi gölgenin genel şeklini tanımlar. androidx.compose.foundation.shape paketindeki tüm geometrileri ve Material Expressive şekillerini kullanabilir.
Temel bir gölge uygulamak için dropShadow() değiştiricisini composable zincirinize ekleyerek yarıçapı, rengi ve yayılmayı sağlayın. Gölgenin üzerinde görünen
purpleColor arka planın, purpleColor değiştiricisinden sonra çizildiğini unutmayın:dropShadow()
@Composable fun SimpleDropShadowUsage() { Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(300.dp) .dropShadow( shape = RoundedCornerShape(20.dp), shadow = Shadow( radius = 10.dp, spread = 6.dp, color = Color(0x40000000), offset = DpOffset(x = 4.dp, 4.dp) ) ) .align(Alignment.Center) .background( color = Color.White, shape = RoundedCornerShape(20.dp) ) ) { Text( "Drop Shadow", modifier = Modifier.align(Alignment.Center), fontSize = 32.sp ) } } }
Kodla ilgili önemli noktalar
dropShadow()değiştiricisi, içtekiBoxöğesine uygulanır. Gölge aşağıdaki özelliklere sahiptir:- Yuvarlak dikdörtgen şekli (
RoundedCornerShape(20.dp)) - Kenarları yumuşak ve dağınık hale getiren
10.dpbulanıklık yarıçapı - Gölgenin boyutunu genişleten ve onu, gölgeyi oluşturan kutudan daha büyük hale getiren
6.dpyayılımı - Gölgeyi yarı şeffaf hale getiren
0.5falfa değeri
- Yuvarlak dikdörtgen şekli (
- Gölge tanımlandıktan sonra .
background()değiştiricisi uygulanır.Boxbeyaz renkle doldurulur.- Arka plan, gölgeyle aynı yuvarlatılmış dikdörtgen şekline kırpılır.
Sonuç
İç gölgeler uygulama
dropShadow() öğesinin tersi bir efekt oluşturmak için Modifier.innerShadow() öğesini kullanın. Bu öğe, bir öğenin alttaki yüzeye gömülmüş veya bastırılmış olduğu yanılsamasını oluşturur.
İç gölgeler oluştururken sıra önemlidir. innerShadow() değiştiricisi, içeriğin üst kısmını temel alır. Gölgenin görünür olduğundan emin olmak için genellikle aşağıdaki adımları uygularsınız:
- Arka plan içeriğinizi çizin.
- İçbükey görünüm oluşturmak için
innerShadow()değiştiricisini uygulayın.
innerShadow() simgesi arka plandan önce yerleştirilirse arka plan, gölgenin üzerine çizilerek gölge tamamen gizlenir.
Aşağıdaki örnekte innerShadow() öğesinin RoundedCornerShape üzerinde uygulanması gösterilmektedir:
@Composable fun SimpleInnerShadowUsage() { Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) // note that the background needs to be defined before defining the inner shadow .background( color = Color.White, shape = RoundedCornerShape(20.dp) ) .innerShadow( shape = RoundedCornerShape(20.dp), shadow = Shadow( radius = 10.dp, spread = 2.dp, color = Color(0x40000000), offset = DpOffset(x = 6.dp, 7.dp) ) ) ) { Text( "Inner Shadow", modifier = Modifier.align(Alignment.Center), fontSize = 32.sp ) } } }
Modifier.innerShadow() uygulaması.Kullanıcı etkileşiminde gölgeleri canlandır
Gölgelerinizin kullanıcı etkileşimlerine yanıt vermesini sağlamak için gölge özelliklerini Compose'un animasyon API'leriyle entegre edebilirsiniz. Kullanıcı bir düğmeye bastığında, örneğin, anlık görsel geri bildirim sağlamak için gölge değişebilir.
Aşağıdaki kod, gölgeyle birlikte "basılmış" efekti oluşturur (yüzeyin ekrana doğru itildiği yanılsaması):
@Composable fun AnimatedColoredShadows() { SnippetsTheme { Box(Modifier.fillMaxSize()) { val interactionSource = remember { MutableInteractionSource() } val isPressed by interactionSource.collectIsPressedAsState() // Create transition with pressed state val transition = updateTransition( targetState = isPressed, label = "button_press_transition" ) fun <T> buttonPressAnimation() = tween<T>( durationMillis = 400, easing = EaseInOut ) // Animate all properties using the transition val shadowAlpha by transition.animateFloat( label = "shadow_alpha", transitionSpec = { buttonPressAnimation() } ) { pressed -> if (pressed) 0f else 1f } // ... val blueDropShadow by transition.animateColor( label = "shadow_color", transitionSpec = { buttonPressAnimation() } ) { pressed -> if (pressed) Color.Transparent else blueDropShadowColor } // ... Box( Modifier .clickable( interactionSource, indication = null ) { // ** ...... **// } .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = 0.dp, color = blueDropShadow, offset = DpOffset(x = 0.dp, -(2).dp), alpha = shadowAlpha ) ) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = 0.dp, color = darkBlueDropShadow, offset = DpOffset(x = 2.dp, 6.dp), alpha = shadowAlpha ) ) // note that the background needs to be defined before defining the inner shadow .background( color = Color(0xFFFFFFFF), shape = RoundedCornerShape(70.dp) ) .innerShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 8.dp, spread = 4.dp, color = innerShadowColor2, offset = DpOffset(x = 4.dp, 0.dp) ) ) .innerShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 20.dp, spread = 4.dp, color = innerShadowColor1, offset = DpOffset(x = 4.dp, 0.dp), alpha = innerShadowAlpha ) ) ) { Text( "Animated Shadows", // ... ) } } } }
Kodla ilgili önemli noktalar
transition.animateColorvetransition.animateFloatile basıldığında animasyon uygulanacak parametrelerin başlangıç ve bitiş durumlarını bildirir.updateTransitionkullanır ve tüm animasyonların senkronize edildiğini doğrulamak için seçilentargetState (targetState = isPressed)ile birlikte sağlar.isPressedher değiştiğinde, geçiş nesnesi tüm alt özelliklerin animasyonunu mevcut değerlerinden yeni hedef değerlere otomatik olarak yönetir.- Geçişin zamanlamasını ve yumuşak geçişini kontrol eden
buttonPressAnimationözelliğini tanımlar. 400 milisaniye süreli birtween(arada anlamına gelir) veEaseInOuteğrisi belirtir. Bu eğri, animasyonun yavaş başladığı, ortada hızlandığı ve sonunda yavaşladığı anlamına gelir. - Aşağıdakiler de dahil olmak üzere, tüm animasyonlu özellikleri uygulayarak görsel öğeyi oluşturan bir değiştirici işlevler zinciri içeren bir
Boxtanımlar:- .
clickable():Boxöğesini etkileşimli hale getiren bir değiştiricidir. .dropShadow(): Önce iki dış gölge uygulanır. Renk ve alfa özellikleri, animasyonlu değerlere (blueDropShadowvb.) bağlıdır ve ilk yükseltilmiş görünümü oluşturur..innerShadow(): Arka planın üzerine iki iç gölge çizilir. Bu özellikler, diğer animasyonlu değerler grubuna (innerShadowColor1vb.) bağlanır ve girintili görünümü oluşturur.
- .
Sonuç
Renk geçişli gölgeler oluşturma
Gölgeler düz renklerle sınırlı değildir. Shadow API, Brush kabul eder. Bu sayede gradyan gölgeler oluşturabilirsiniz.
Box( modifier = Modifier .width(240.dp) .height(200.dp) .dropShadow( shape = RoundedCornerShape(70.dp), shadow = Shadow( radius = 10.dp, spread = animatedSpread.dp, brush = Brush.sweepGradient( colors ), offset = DpOffset(x = 0.dp, y = 0.dp), alpha = animatedAlpha ) ) .clip(RoundedCornerShape(70.dp)) .background(Color(0xEDFFFFFF)), contentAlignment = Alignment.Center ) { Text( text = breathingText, color = Color.Black, style = MaterialTheme.typography.bodyLarge ) }
Kodla ilgili önemli noktalar
dropShadow()kutunun arkasına gölge ekler.brush = Brush.sweepGradient(colors), gölgeyi önceden tanımlanmışcolorslistesinde dönen bir gradyanla renklendirerek gökkuşağı benzeri bir efekt oluşturur.
Sonuç
"Nefes alma" animasyonuyla dropShadow() degrade oluşturmak için fırçayı gölge olarak kullanabilirsiniz:
Gölgeleri birleştirme
Çeşitli efektler oluşturmak için dropShadow() ve innerShadow() değiştiricilerini birleştirip katmanlayabilirsiniz. Aşağıdaki bölümlerde, bu teknikle nasıl neomorfik, neobrutalist ve gerçekçi gölgeler oluşturacağınız gösterilmektedir.
Neumorfik gölgeler oluşturma
Neumorfik gölgeler, arka plandan doğal olarak ortaya çıkan yumuşak bir görünüme sahiptir. Neumorfik gölgeler oluşturmak için aşağıdakileri yapın:
- Arka planıyla aynı renklere sahip bir öğe kullanın.
- İki soluk, zıt gölge uygulayın: bir köşeye açık, diğer köşeye koyu gölge.
Aşağıdaki snippet, dropShadow() değiştiricilerini iki katman halinde kullanarak neomorfik efekt oluşturur:
@Composable fun NeumorphicRaisedButton( shape: RoundedCornerShape = RoundedCornerShape(30.dp) ) { val bgColor = Color(0xFFe0e0e0) val lightShadow = Color(0xFFFFFFFF) val darkShadow = Color(0xFFb1b1b1) val upperOffset = -10.dp val lowerOffset = 10.dp val radius = 15.dp val spread = 0.dp Box( modifier = Modifier .fillMaxSize() .background(bgColor) .wrapContentSize(Alignment.Center) .size(240.dp) .dropShadow( shape, shadow = Shadow( radius = radius, color = lightShadow, spread = spread, offset = DpOffset(upperOffset, upperOffset) ), ) .dropShadow( shape, shadow = Shadow( radius = radius, color = darkShadow, spread = spread, offset = DpOffset(lowerOffset, lowerOffset) ), ) .background(bgColor, shape) ) }
Yeni brutalist gölgeler oluşturma
Neobrutalist stil, yüksek kontrastlı, bloklu düzenler, canlı renkler ve kalın kenarlıklar içerir. Bu efekti oluşturmak için aşağıdaki snippet'te gösterildiği gibi, sıfır bulanıklığa ve belirgin bir ofsete sahip bir dropShadow() kullanın:
@Composable fun NeoBrutalShadows() { SnippetsTheme { val dropShadowColor = Color(0xFF007AFF) val borderColor = Color(0xFFFF2D55) Box(Modifier.fillMaxSize()) { Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(0.dp), shadow = Shadow( radius = 0.dp, spread = 0.dp, color = dropShadowColor, offset = DpOffset(x = 8.dp, 8.dp) ) ) .border( 8.dp, borderColor ) .background( color = Color.White, shape = RoundedCornerShape(0.dp) ) ) { Text( "Neobrutal Shadows", modifier = Modifier.align(Alignment.Center), style = MaterialTheme.typography.bodyMedium ) } } } }
Gerçekçi gölgeler oluşturma
Gerçekçi gölgeler, fiziksel dünyadaki gölgeleri taklit eder. Birincil ışık kaynağıyla aydınlatılmış gibi görünürler. Bu da hem doğrudan bir gölge hem de daha dağınık bir gölgeyle sonuçlanır. Aşağıdaki snippet'te gösterildiği gibi, gerçekçi gölge efektleri oluşturmak için farklı özelliklere sahip birden fazla dropShadow() ve innerShadow() örneğini üst üste yerleştirebilirsiniz:
@Composable fun RealisticShadows() { Box(Modifier.fillMaxSize()) { val dropShadowColor1 = Color(0xB3000000) val dropShadowColor2 = Color(0x66000000) val innerShadowColor1 = Color(0xCC000000) val innerShadowColor2 = Color(0xFF050505) val innerShadowColor3 = Color(0x40FFFFFF) val innerShadowColor4 = Color(0x1A050505) Box( Modifier .width(300.dp) .height(200.dp) .align(Alignment.Center) .dropShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 40.dp, spread = 0.dp, color = dropShadowColor1, offset = DpOffset(x = 2.dp, 8.dp) ) ) .dropShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 4.dp, spread = 0.dp, color = dropShadowColor2, offset = DpOffset(x = 0.dp, 4.dp) ) ) // note that the background needs to be defined before defining the inner shadow .background( color = Color.Black, shape = RoundedCornerShape(100.dp) ) // // .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 12.dp, spread = 3.dp, color = innerShadowColor1, offset = DpOffset(x = 6.dp, 6.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 4.dp, spread = 1.dp, color = Color.White, offset = DpOffset(x = 5.dp, 5.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 12.dp, spread = 5.dp, color = innerShadowColor2, offset = DpOffset(x = (-3).dp, (-12).dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 3.dp, spread = 10.dp, color = innerShadowColor3, offset = DpOffset(x = 0.dp, 0.dp) ) ) .innerShadow( shape = RoundedCornerShape(100.dp), shadow = Shadow( radius = 3.dp, spread = 9.dp, color = innerShadowColor4, offset = DpOffset(x = 1.dp, 1.dp) ) ) ) { Text( "Realistic Shadows", modifier = Modifier.align(Alignment.Center), fontSize = 24.sp, color = Color.White ) } } }
Kodla ilgili önemli noktalar
- Farklı özelliklere sahip iki zincirli
dropShadow()değiştirici uygulanır ve ardından birbackground()değiştirici gelir. - Zincirleme
innerShadow()değiştiriciler, bileşenin kenarında metalik çerçeve efekti oluşturmak için uygulanır.
Sonuç
Önceki kod snippet'i aşağıdakileri üretir: