I’m trying out server-driven UI where JSON sends m...
# compose
r
I’m trying out server-driven UI where JSON sends modifiers array to apply on view in particular order. How to combine multiple modifiers while iterating list? 🧵
Copy code
fun Modifier.render(modifiers: List<ModifierComponent>) =
    composed {
        val modifier = Modifier
        modifiers.forEach {
            when (it) {
                is AlphaComponent -> modifier.then(alphaRender(it))
                is AttrsComponent -> modifier.then(attrsRender(it))
                is BackgroundComponent -> modifier.then(bgRender(it))
                is BorderComponent -> modifier.then(borderRender(it))
                is PaddingComponent -> modifier.then(paddingRender(it))
                is RotateComponent -> modifier.then(rotateRender(it))
                is ShapeComponent -> modifier.then(shapeRender(it))
                is SizeComponent -> modifier.then(sizeRender(it))
                is WrapComponent -> modifier.then(wrapRender(it))
                is AspectRatioComponent -> modifier.then(aspectRatioRender(it))
            }
        }
        this.then(modifier)
    }
this approach is not giving me combined result of modifiers
a
Should be
Copy code
modifier = modifier.then(alphaRender(it))
maybe?
a
You are discarding the result of
when
.
Copy code
var modifier = Modifier
modifiers.forEach {
    modifier = when(it) { ... }
}
This should work.
Also there’s no need to used
composed
.
The point is that
Modifier.then()
returns a new instance.
r
inside
bgRender
and
borderRender
i’m consuming custom theme colors so
composed
required der.
a
Then just make them
composed
. You don't need to make this modifier
composed
.
Generally you should only use
composed
if you need to call composable functions.
r
is this syntax correct I’ve removed
composed
where its not required.
Copy code
fun Modifier.rotateRender(rotateComponent: RotateComponent? = null) = apply {
    if (rotateComponent?.rotate != null) {
        this.rotate(rotateComponent.rotate)
    }
}

fun Modifier.alphaRender(alphaComponent: AlphaComponent? = null) = apply {
    if (alphaComponent?.alpha != null) {
        this.alpha(alphaComponent.alpha)
    }
}
this is not reflecting any changes
Copy code
modifier = Modifier
                    .rotateRender(RotateComponent(rotate = 10F))
                    .alphaRender(AlphaComponent(alpha = 0.5F))
a
It’s the same problem. Every time you add a new modifier it is a new instance and you are discarding the results of
Modifier.rotate()
and
Modifier.alpha()
. Should be like this:
Copy code
fun Modifier.rotateRender(rotateComponent: RotateComponent? = null) =
    if (rotateComponent?.rotate != null) rotate(rotateComponent.rotate) else this
🙌 1
e
no need for mutable
var modifier
, just do
Copy code
modifiers.fold(Modifier) { modifier, component ->
    when (component) {
        is AlphaComponent -> modifier.then(alphaRender(it))
        ...
    }
}
r
Ive changed all the helper functions.
Copy code
fun Modifier.rotateRender(rotateComponent: RotateComponent? = null): Modifier =
    if (rotateComponent?.rotate != null) rotate(rotateComponent.rotate) else this

fun Modifier.alphaRender(alphaComponent: AlphaComponent? = null): Modifier =
    if (alphaComponent?.alpha != null) alpha(alphaComponent.alpha) else this
its working fine for
Copy code
Text(
                    text = "Hello",
                    modifier = Modifier
                        .alphaRender(alpha)
                        .rotateRender(rotate)
                )
but unable to get combined result when iterating list
Copy code
fun Modifier.renderTest(modifiers: List<ModifierComponent>): Modifier {
    var modifier: Modifier = this
    modifiers.forEach {
        modifier = when (it) {
            is AlphaComponent -> alphaRender(it)
            is RotateComponent -> rotateRender(it)
            else -> Modifier
        }
        this.then(modifier)
    }
    return this
}
val list = listOf(alpha, rotate)
Text(
    text = "Hello",
    modifier = Modifier
        .renderTest(list)
)
its picking only the last modifier in the list.
Copy code
fun Modifier.renderTest(modifiers: List<ModifierComponent>): Modifier {
    return modifiers.fold(this, { mod, component ->
        when (component) {
            is AlphaComponent -> mod.alphaRender(component)
            is RotateComponent -> mod.rotateRender(component)
            else -> mod
        }
    })
}
this solution worked thanks alot @ephemient @Albert Chang
a
It's still the same problem. You have to always keep in mind that adding a new
Modifier
results in a new
Modifier
instance. You are adding `Modifier`s to
modifier
variable, which makes it a new instance, but you are returning
this
which is the initial instance. You should return
modifier
instead.
1