diff --git a/android/ui/src/main/java/com/trafi/ui/Badge.kt b/android/ui/src/main/java/com/trafi/ui/Badge.kt index a42b2c53a..498d98242 100644 --- a/android/ui/src/main/java/com/trafi/ui/Badge.kt +++ b/android/ui/src/main/java/com/trafi/ui/Badge.kt @@ -24,6 +24,16 @@ import com.trafi.ui.theme.MaasTheme import com.trafi.ui.theme.currentTheme import com.trafi.ui.theme.darkColors +/** + * + * Badge does not work with LazyColumn and LazyColumnFor, because parent ConstraintLayout of badge + * has parameter preferredWidth(IntrinsicSize.Min). Without this parameter it is not possible to + * to set custom width to badge. + * + * One of the options is to use same modifier for ConstraintLayout and child layout + * (Surface or other) but then subbadgeIcon flies away from badge. + */ + @Composable private val constants get() = BadgeConstants(currentTheme) @@ -52,7 +62,7 @@ fun Badge( modifier = modifier, icon = icon, subbadgeIcon = subbadgeIcon, - isEnabled = isEnabled + isEnabled = isEnabled, ) } else { StackedBadge( @@ -60,7 +70,8 @@ fun Badge( badge = badge, alternativeBadges = alternativeBadges, icon = icon, - badgeType = badgeType + badgeType = badgeType, + subbadgeIcon = subbadgeIcon, ) } } @@ -75,15 +86,15 @@ private fun SingleBadge( subbadgeIcon: ImageVector? = null, isEnabled: Boolean = true, ) { - ConstraintLayout { + ConstraintLayout( + modifier = modifier.preferredWidth(IntrinsicSize.Min) + ) { Surface( color = if (isEnabled) badge.backgroundColor else constants.disabledColor, contentColor = badge.contentColor ?: constants.defaultContentColor, shape = RoundedCornerShape(badgeType.badgeRounding), - modifier = modifier.sizeIn(minHeight = badgeType.badgeHeight) - .constrainAs(createRef()) { - bottom.linkTo(parent.bottom) - } + modifier = Modifier.sizeIn(minHeight = badgeType.badgeHeight) + .fillMaxWidth() ) { BadgeFiller( badgeType = badgeType, @@ -109,7 +120,6 @@ private fun SingleBadge( } } - @OptIn(ExperimentalLayout::class) @Composable private fun StackedBadge( @@ -120,7 +130,9 @@ private fun StackedBadge( subbadgeIcon: ImageVector? = null, alternativeBadges: List = listOf(), ) { - ConstraintLayout { + ConstraintLayout( + modifier = modifier.preferredWidth(IntrinsicSize.Min) + ) { val altBadgesSublist = alternativeBadges.take(constants.maxStackedBadgesNumber) altBadgesSublist.forEachIndexed { index, smallScheduleBadge -> Surface( @@ -128,7 +140,8 @@ private fun StackedBadge( contentColor = smallScheduleBadge.contentColor ?: constants.defaultContentColor, border = BorderStroke(constants.borderWidth, color = constants.borderColor), shape = RoundedCornerShape(badgeType.badgeRounding), - modifier = modifier.height(badgeType.badgeHeight + (index * 4).dp) + modifier = Modifier.height(badgeType.badgeHeight + (index * 4).dp) + .fillMaxWidth() .padding(top = (index * 4).dp) ) { BadgeFiller( @@ -146,9 +159,10 @@ private fun StackedBadge( contentColor = badge.contentColor ?: constants.defaultContentColor, border = BorderStroke(constants.borderWidth, color = constants.borderColor), shape = RoundedCornerShape(badgeType.badgeRounding), - modifier = modifier + modifier = Modifier .sizeIn(minHeight = badgeType.badgeHeight + (altBadgesSublist.size * 4).dp + (constants.borderWidth * 2)) .padding(top = (altBadgesSublist.size * 4).dp) + .fillMaxWidth() ) { BadgeFiller( badgeType = badgeType, @@ -176,6 +190,7 @@ private fun StackedBadge( } } +@ExperimentalLayout @Composable private fun BadgeFiller( badgeType: BadgeType, @@ -184,37 +199,44 @@ private fun BadgeFiller( icon: ImageVector?, isHiddenLayoutFiller: Boolean = false, ) { - Row( - modifier = Modifier.padding( - horizontal = badgeType.getHorizontalPadding(isStackedBadge), - vertical = badgeType.verticalPadding - ), - horizontalArrangement = Arrangement.spacedBy(constants.spacer) + Box( + contentAlignment = Alignment.Center, ) { - if (isHiddenLayoutFiller) { - Box(modifier = Modifier.align(Alignment.CenterVertically).width(constants.iconWidth)) {} - } else { - icon?.let { - Image( - icon, - colorFilter = ColorFilter.tint(badge.contentColor - ?: constants.defaultContentColor), + Row( + modifier = Modifier + .padding( + horizontal = badgeType.getHorizontalPadding(isStackedBadge), + vertical = badgeType.verticalPadding + ), + ) { + if (isHiddenLayoutFiller) { + Box(modifier = Modifier.align(Alignment.CenterVertically) + .width(constants.iconWidth)) {} + } else { + icon?.let { + Image( + icon, + colorFilter = ColorFilter.tint(badge.contentColor + ?: constants.defaultContentColor), + modifier = Modifier.align(Alignment.CenterVertically) + .width(constants.iconWidth) + .padding(bottom = 1.dp) + .height(constants.iconHeight) + ) + } + } + badge.text?.let { + Text( + text = badge.text, + color = badge.contentColor ?: constants.defaultContentColor, + style = badgeType.textStyle, modifier = Modifier.align(Alignment.CenterVertically) - .width(constants.iconWidth) - .height(constants.iconHeight) + .padding(bottom = 1.dp, + start = if (icon != null) constants.spacer else 0.dp) + .wrapContentHeight(unbounded = true) ) } } - badge.text?.let { - Text( - text = badge.text, - color = badge.contentColor ?: constants.defaultContentColor, - style = badgeType.textStyle, - modifier = Modifier.align(Alignment.CenterVertically) - .padding(bottom = 1.dp) - .wrapContentHeight(unbounded = true) - ) - } } } @@ -225,7 +247,6 @@ private val BadgeType.badgeHeight: Dp Medium -> constants.minHeightMedium } - @Composable private val BadgeType.badgeRounding: Dp get() = when (this) { @@ -233,7 +254,6 @@ private val BadgeType.badgeRounding: Dp Medium -> constants.cornerRadiusMedium } - @Composable private fun BadgeType.getHorizontalPadding(isStackedBadge: Boolean): Dp { return when (this) { @@ -251,7 +271,6 @@ private val BadgeType.verticalPadding: Dp Medium -> constants.verticalPaddingMedium } - @Composable private val BadgeType.textStyle: TextStyle get() = when (this) { @@ -283,7 +302,8 @@ fun BadgePreviewWithSubbadge() { badge = BadgeInfo("5G", Color.Magenta), icon = vectorResource(R.drawable.providers_ubahn_xs), subbadgeIcon = vectorResource(id = R.drawable.warning_warning_s), - badgeType = Medium + modifier = Modifier.width(120.dp).padding(12.dp), + badgeType = Medium, ) } @@ -366,6 +386,8 @@ fun StackedBadgePreviewWithSubbadge() { BadgeInfo("135", Color.Magenta), BadgeInfo("135", Color.Magenta)), icon = vectorResource(R.drawable.providers_ubahn_xs), - badgeType = Medium + subbadgeIcon = vectorResource(id = R.drawable.warning_warning_s), + modifier = Modifier.width(150.dp).padding(12.dp), + badgeType = Medium, ) } \ No newline at end of file