Reputation: 1640
Why is it that border
modifier is not applied when used with .apply { }
?
val selected = remember { mutableStateOf(true) }
val selectableModifier = Modifier
.padding(horizontal = 5.dp, vertical = 8.dp)
.apply {
// this changes, but border is not applied
println("$selected changed")
if (selected) {
border(
BorderStroke(1.dp, MaterialTheme.colors.primaryVariant),
RoundedCornerShape(13.dp)
)
}
}
Upvotes: 12
Views: 2153
Reputation: 6427
You can use extension like:
/**
* Calling standard `apply()` on Modifier has no effect,
* because it returns the origin Modifier, not the updated one.
*
* This function will call `run` under the hood instead.
* It will return updated instance if the [condition] is met or origin Modifier if not.
*/
inline fun Modifier.applyOnModifier(condition: Boolean, block: Modifier.() -> Modifier): Modifier =
if (condition) block.invoke(this) else this
and call it like:
@Composable
fun MyCustomCardWithClick(
modifier: Modifier,
onClick: (() -> Unit)? = null,
) {
Card(
modifier = modifier
.applyOnModifier(onClick != null) {
clickable { onClick?.invoke() }
}
) { }
}
Upvotes: 0
Reputation: 751
When you call a Modifier's method it returns the Modifier itself with new changes. So you have to do something like that
var modifier = Modifier
modifier = modifier.doSomeThing()
modifier = modifier.doOtherThing()
OR use then
val modifier = Modifier
.then(Modifier.doSomeThing())
.then(Modifier.doOtherThing())
You can make conditional then extension method.
fun Modifier.thenIf(condition: Boolean, other: Modifier): Modifier =
if (condition) this.then(other) else this
And use it like that
val modifier = Modifier
.then(Modifier.doSomeThing())
.then(Modifier.doOtherThing())
.thenIf(canClick==true,Modifier.doConditionalThing())
Upvotes: 3
Reputation: 88497
apply
always returns this
to output. You can change this
inside, but in case with modifiers they are immutable, you expected to create a new modifier based on the current one. That's why your border
is being ignored.
Instead you can use run
, and you have to return something: newly created modifier or this
. Check out more about kotlin scope functions.
val selected by remember { mutableStateOf(true) }
val selectableModifier = Modifier
.padding(horizontal = 5.dp, vertical = 8.dp)
.run {
if (selected) {
border(
BorderStroke(1.dp, MaterialTheme.colors.primaryVariant),
RoundedCornerShape(13.dp)
)
} else {
this
}
}
Upvotes: 23