Home > Software design >  Gradient backround for FAB in Jetpack compose
Gradient backround for FAB in Jetpack compose

Time:10-16

I want to add a Floating Action Button with a gradient background in Jetpack Compose. I have the following snippet to do so:

FloatingActionButton(
    onClick = {
        coroutineScope.safeLaunch {
            navController.navigate("AddTodoPage") {
                launchSingleTop = true
            }
        }
    },
    shape = RoundedCornerShape(14.dp),
    backgroundColor = Color.Transparent,
    modifier = Modifier
        .constrainAs(addFab) {
            bottom.linkTo(parent.bottom)
            end.linkTo(parent.end)
        }
        .offset(x = (-16).dp, y = (-24).dp)
        .background(
            brush = Brush.verticalGradient(
                colors = BluePinkGradient()
            ),
            shape = RoundedCornerShape(14.dp)
        )

) {
    Icon(
        painter = painterResource(id = R.drawable.ic_add),
        contentDescription = "Add icon",
        tint = Color.White
    )
}

fun BluePinkGradient(inverse: Boolean = false) = when (inverse) {
    true -> listOf(
        MutedBlue,
        MutedPink
    )
    false -> listOf(
        MutedPink,
        MutedBlue
    )
}
val MutedBlue = Color(0xFF26A69A)
val MutedPink = Color(0xFFEC407A)

But from the image below, the button has a "Whitish" shade on the plus icon. How can I remove that shade or a better way to set the FAB background to a gradient? Fab Image

CodePudding user response:

'"Whitish" shade on the plus icon' is the result of elevation parameter. You can zero it, but it doesn't looks like you need FAB in the first place.

As you need to custom the button that much, you can use IconButton instead:

IconButton(
    onClick = {
    },
    modifier = Modifier
        .background(
            brush = Brush.verticalGradient(
                colors = BluePinkGradient()
            ),
            shape = RoundedCornerShape(14.dp)
        )

) {
    Icon(
        painter = painterResource(id = R.drawable.ic_undo),
        contentDescription = "Add icon",
        tint = Color.White
    )
}

FloatingActionButton is only applying some Material defaults to the content, it doesn't make it really floating, it has to be done with the container.

CodePudding user response:

I have developed the following solution, which I have confirmed as working:

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun CrazyFloatingActionButton(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    shape: Shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50)),
    gradient: List<Color>,
    contentColor: Color = contentColorFor(gradient[0]),
    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),
    content: @Composable () -> Unit
) {
    Surface(
        modifier = modifier,
        shape = shape,
        contentColor = contentColor,
        elevation = elevation.elevation(interactionSource).value,
        onClick = onClick,
        role = Role.Button,
        interactionSource = interactionSource,
        indication = rememberRipple()
    ) {
        CompositionLocalProvider(LocalContentAlpha provides contentColor.alpha) {
            ProvideTextStyle(MaterialTheme.typography.button) {
                Box(
                    modifier = Modifier
                        .defaultMinSize(minWidth = 56.dp, minHeight = 56.dp)
                        .background(brush = Brush.verticalGradient(gradient)),
                    contentAlignment = Alignment.Center
                ) { content() }
            }
        }
    }
}

Just prepend Crazy to your Composable and you should be good to go.

  • Related