Градиентный фон для FAB в Jetpack compose

#android #kotlin #android-jetpack-compose

Вопрос:

Я хочу добавить плавающую кнопку действия с градиентным фоном в Jetpack Compose. Для этого у меня есть следующий фрагмент:

 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)
 

Но на изображении ниже кнопка имеет «беловатый» оттенок на значке «плюс». Как я могу удалить этот оттенок или лучший способ установить потрясающий фон в градиент?
Потрясающее Изображение

Ответ №1:

«»Беловатый» оттенок на значке плюса » является результатом elevation параметра. Вы можете обнулить его, но, похоже, в первую очередь он вам не нужен.

Поскольку вам нужно так сильно настроить кнопку, вы можете использовать IconButton вместо этого:

 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 это только применение некоторых материалов по умолчанию к содержимому, это не делает его действительно плавающим, это должно быть сделано с контейнером.

Комментарии:

1. Спасибо, это сработало для меня, но мне пришлось изменить и добавить Card составной контейнер для .offset(x = (-16).dp, y = (-24).dp), и. elevation Смещение вело себя странно, когда было установлено на IconButton .

Ответ №2:

Я разработал следующее решение, которое я подтвердил как рабочее:

 @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() }
            }
        }
    }
}
 

Просто добавьте Crazy к своему составному, и вы должны быть готовы к работе.