kotlinandroid-jetpack-compose

apply shadow only to one side of Box in jetpack compose


how to apply shoadow only to one or two side of a Box in jetpack compose ? I want to apply shadow to bottom of this Column :

                     Column(
                        modifier = Modifier
                            .weight(0.7f)
                            .fillMaxHeight()
                            .clip(
                                shape = RoundedCornerShape(
                                    topStart = 0.dp,
                                    topEnd = 0.dp,
                                    bottomStart = 16.dp,
                                    bottomEnd = 16.dp
                                )
                            )
                            .background(Color.White)

                    )

Solution

  • You can do is in various ways. 2 ways are to have bigger shape to clip in bottom direction either by creating GenericShape and using this only in clip Modifier or using drawWithContent with clipRect.

    Since clipRect is easy, i will only post that one. Result is

    enter image description here

    How you clip drawn content also determines how shadow is drawn. Shadow is nothing other than a shape drawn with stroke. You can refer this answer for more details about shadow Modifier.

    @Preview
    @Composable
    fun SidedShadow() {
        Column(
            modifier = Modifier.fillMaxSize().padding(16.dp)
        ) {
    
            val elevation = 4.dp
            Box(
                modifier = Modifier
                    .padding(vertical = 8.dp)
                    .size(200.dp, 100.dp)
    
                    .drawWithContent {
                        clipRect(
                            left = 0f,
                            top = 0f,
                            right = size.width,
                            bottom = size.height + elevation.toPx()
                        ){
                            this@drawWithContent.drawContent()
                        }
                    }
                    .shadow(
                        elevation = elevation,
                        shape = RoundedCornerShape(
                            topStart = 0.dp,
                            topEnd = 0.dp,
                            bottomStart = 16.dp,
                            bottomEnd = 16.dp,
                        ),
                    )
                    .background(Color.White)
            )
        }
    

    }

    3 sided shadow

    Change left and right to include shadow as below. In jetpack Compose you can draw anything out of Composable but using any clipping technique you limit overflow borders you define.

    enter image description here

    .drawWithContent {
        clipRect(
            left = -elevation.toPx(),
            top = 0f,
            right = size.width + elevation.toPx(),
            bottom = size.height + elevation.toPx()
        ) {
            this@drawWithContent.drawContent()
        }
    }