In the shopping list item composable, I am reducing the alpha value on the whole item by changing the alpha value on it's parent Row
composable, but I want to exclude a child Icon
composable from receiving the parent Row
's alpha change and retain a 100% alpha value. I set the modifier on the child Icon
to alpha(1f)
, but it is not working. The alpha change on the parent is also propagating to the child despite this. Is it possible exclude the child from the parent's alpha change?
Composable
@Composable
fun ShoppingListScreenItem(
rowModifier: Modifier = Modifier,
item: ShoppingListItem,
mainViewModel: ShoppingListScreenViewModel,
onNavigateToAddEditItemScreenFromItemStrip: (ShoppingListItem) -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 3.dp, bottom = 5.dp)
.then(rowModifier)
.alpha(if (item.isItemDisabled) 0.35f else 1f)
.clickable {
onNavigateToAddEditItemScreenFromItemStrip(item)
},
verticalAlignment = Alignment.CenterVertically,
) {
...
if(mainViewModel.shoppingListState.value!!.sortOrder != "Custom" && !item.isInCart) {
//I want to exclude this child composable
IconToggleButton(
checked = item.isItemDisabled,
onCheckedChange = {
scope.launch {
mainViewModel.updateShoppingListItemDisabledInDb(item, it)
}
},
) {
Icon(
modifier = Modifier.alpha(1f).size(26.dp),
painter = painterResource(id = R.drawable.baseline_disabled_visible_24),
contentDescription = "Toggle disable the item strip",
)
}
}
}
}
CodePudding user response:
This can be achieved using Layout and placeable.placeWithLayer and Modifier.layoutId to select which Composable is to be used with default alpha as.
This is a custom Column, you can customize Layout as required, purpose is to show Modifier.layoutId
usage and Placeable.placeRelativeWithLayer
to apply any desired graphic layer property to specific Composable in layout phase.
Result
Usage
MyLayout(
alpha = .5f
) {
Text("Default Alpha", fontSize = 20.sp)
Text("Default Alpha", fontSize = 20.sp)
Text("Custom Alpha", fontSize = 20.sp), modifier = Modifier.layoutId("full_alpha"))
Text("Default Alpha", fontSize = 20.sp)
Image(painter = painterResource(id = R.drawable.landscape5), contentDescription = "")
}
Implementation
@Composable
private fun MyLayout(
modifier: Modifier = Modifier,
alpha: Float = 1f,
content: @Composable () -> Unit
) {
val measurePolicy = MeasurePolicy { measurables, constraints ->
val fullAlphaIndex = measurables.indexOfFirst {
it.layoutId == "full_alpha"
}
val placeablesWidth = measurables.map { measurable ->
measurable.measure(constraints)
}
val hasBoundedWidth = constraints.hasBoundedWidth
val hasFixedWidth = constraints.hasFixedWidth
val width =
if (hasBoundedWidth && hasFixedWidth) constraints.maxWidth
else placeablesWidth.maxOf { it.width }
val height = placeablesWidth.sumOf {
it.height
}
var posY = 0
layout(width, height) {
placeablesWidth.forEachIndexed { index, placeable ->
placeable.placeRelativeWithLayer(0, posY) {
if (index == fullAlphaIndex) {
this.alpha = 1f
} else {
this.alpha = alpha
}
}
posY = placeable.height
}
}
}
Layout(
modifier = modifier,
content = content,
measurePolicy = measurePolicy
)
}