郭大鹏
郭大鹏

Reputation: 193

How do I set a shadow color for Jetpack Compose?

Sorry, I can hardly speak English.

machine translation:

How do I set a shadow color for Jetpack Compose?

I can set shadows, but they're ugly.

Jetpack Compose code:

Surface(
    modifier = Modifier.width(160.dp).height(56.dp),
    shape = CircleShape,
    elevation = 2.dp,
) {
    ...
}

I want to create a shadow in the code below.

SwiftUI code:

ZStack {
    ...
}
.shadow(color: Color("button_shadow"), radius: 4, x: 0, y: 2)
.shadow(color: Color("button_shadow"), radius: 20, x: 0, y: 4)

Dark mode also requires a white shadow.

enter image description here

enter image description here

You want to be able to customize the color of the shadow.

Upvotes: 17

Views: 32181

Answers (6)

Fateme Afshari
Fateme Afshari

Reputation: 484

You can use the code below to add a colorful shadow to your Modifier:

    fun Modifier.advanceShadow(
    color: Color = Color.Black,
    borderRadius: Dp = 16.dp,
    blurRadius: Dp = 16.dp,
    offsetY: Dp = 0.dp,
    offsetX: Dp = 0.dp,
    spread: Float = 1f,
) = drawBehind {
    this.drawIntoCanvas {
        val paint = Paint()
        val frameworkPaint = paint.asFrameworkPaint()
        val spreadPixel = spread.dp.toPx()
        val leftPixel = (0f - spreadPixel) + offsetX.toPx()
        val topPixel = (0f - spreadPixel) + offsetY.toPx()
        val rightPixel = (this.size.width)
        val bottomPixel = (this.size.height + spreadPixel)

        if (blurRadius != 0.dp) {
            /*
                The feature maskFilter used below to apply the blur effect only works
                with hardware acceleration disabled.
             */
            frameworkPaint.maskFilter =
                (BlurMaskFilter(blurRadius.toPx(), BlurMaskFilter.Blur.NORMAL))
        }

        frameworkPaint.color = color.toArgb()
        it.drawRoundRect(
            left = leftPixel,
            top = topPixel,
            right = rightPixel,
            bottom = bottomPixel,
            radiusX = borderRadius.toPx(),
            radiusY = borderRadius.toPx(),
            paint
        )
    }
}

Upvotes: 3

Nek.12
Nek.12

Reputation: 333

Compose 1.2.0-alpha06 now supports shadow color attribute for the graphics layer modifier! ambientColor and spotColor can change the color of your shadow. It's only useful with shapes though (CircleShape, RectangleShape, RoundedCornerShape, or your custom shape)

fun Modifier.shadow(
    elevation: Dp,
    shape: Shape = RectangleShape,
    clip: Boolean = false,
    elevation: Dp = 0.dp,
    ambientColor: Color = DefaultShadowColor,
    spotColor: Color = DefaultShadowColor,
)

https://developer.android.com/jetpack/androidx/releases/compose-ui#1.2.0-alpha06

Upvotes: 16

vikas kumar
vikas kumar

Reputation: 11018

Well, this has recently changed and you can do it using Material 3 Jetpack Compose library. Just call shadow on modifier and set desired color.

Add dependency

implementation 'androidx.compose.material3:material3:1.0.0-alpha12'
implementation "androidx.compose.ui:1.2.0-beta02"

and add shadow modifier.

 .shadow(
         elevation = 8.dp,
         ambientColor = primaryBlue,
         spotColor = primaryBlue
        )

sample code.

    Image(
        painter = painterResource(id = R.drawable.ic_capture_icon),
        contentDescription = "capture",
        modifier = Modifier
            .padding(20.dp)
            .background(shape = RoundedCornerShape(15.dp), color = primaryBlue)
            .size(60.dp)
            .shadow(
                elevation = 8.dp,
                ambientColor = primaryBlue,
                spotColor = primaryBlue
            )
            .align(Alignment.BottomEnd)
            .padding(12.dp)
            .clickable {
                context.startActivity(Intent(context, GeoSpatialActivity::class.java))
            },
        colorFilter = ColorFilter.tint(color = Color.White)
    )

Upvotes: 5

user12741503
user12741503

Reputation:

the link in the comment of @EpicPandaForce uses converts color to int using android.graphics.Color.Argb(Long) which required Api Level >= 26. I found another link in that gist comment in which function argb is used and it is in API level 1 added.

https://gist.github.com/arthurgonzaga/598267f570e38425fc52f97b30e0619d

Upvotes: 0

Evgenii Doikov
Evgenii Doikov

Reputation: 431

In my case for cycle I use this workaround:

@Composable
fun MyButton(){
    Box(
        modifier = Modifier
            .size(64.dp)
            .background(
                brush = Brush.radialGradient(
                    colors = listOf(
                        Color.Yellow,
                        Color.Transparent
                    )
                )
            )
            .padding(bottom = 4.dp),
        contentAlignment = Alignment.Center
    ) {
        Surface(
            shape = CircleShape,
            modifier = Modifier
                .size(55.dp)
                .background(Color.Transparent)
                .clickable { }
        ) {
            Box(
                modifier = Modifier.padding()
                    .background(Color.Gray),
                contentAlignment = Alignment.Center
            ) {
                Icon(
                    modifier = Modifier.size(35.dp),
                    imageVector = Icons.Filled.Refresh,
                    contentDescription = "",
                    tint =  Color.Yellow
                )
            }
        }

    }
}

there is the preview:

enter image description here

Upvotes: 10

Code Poet
Code Poet

Reputation: 7975

This is not possible at the moment but you can star the issue here: Link to Issue Tracker

The idea would be to have a modifier for the color, opacity, shape etc.

Upvotes: 2

Related Questions