Is there a Modifier, inline function, or another m...
# compose
l
Is there a Modifier, inline function, or another mechanism that reverses the placement order of child composables? So in an example with a Column:
Copy code
@Composable
fun Screen() {
    Column() {
        reversed(true) {
            Text("1")
            Text("2")
            Text("3")
        }
    }
}
3, 2, 1 list would be rendered.
m
Copy code
LazyColumn(reverseLayout = true) {
  item { Text("1") }
  item { Text("2") }
  item { Text("3") }
}
j
Not intended for but could use:
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl )
You can apply that into any layout in compose. Its not certain its implemented however. Using reverse layout on foundation components basically same public.
l
Thanks guys, but what about a general case, such as a Box layout? Maybe a
List<@Composable () -> Unit>
with the
reversed()
function and then
.forEach { it() }
would work.
j
Got curious whats use case?
l
I basically have a mirrored layout at the top and bottom of the screen, which I would like to write only once. In this case, it is a
Column
. This means I could just use the
LazyColumn
with
reverseLayout
, but I wondered whether the same could be done with just a
Column
or any other layout where the children order matters.
j
As long as the composable implements RTL layout direction should be possible using that if thats the case or if its reverse sorting of elements would sort them one layer up I think. Can always do an extension send in list and loop to column reverse order.
Column has layout direction. But be very careful if using Arrangement, make sure using relative variant and not absolute one.
l
Isn't layout direction only horizontal (e.g. ltr, rtl)? How would you set the vertical layout direction for a
Column
?
m
A LazyColumn is probably the "right" way, but I suppose you could do something extremely cursed like
Copy code
Column {
  listOf<@Composable () -> Unit>(
      { Text("1") },
      { Text("2") },
      { Text("3") },
  ).asReversed().forEach { it() }
}
a
You can use a custom arrangement:
Copy code
val ReversedArrangement: Arrangement.Vertical = object : Arrangement.Vertical {

    override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) {
        var current = 0
        for (i in sizes.indices.reversed()) {
            outPositions[i] = current
            current += sizes[i]
        }
    }
}
And use it like
Column(verticalArrangement = ReversedArrangement) { ... }
.
👍 1
🎉 1
j
@Lukáš Kúšik Its same as layout direction both horizontal and vertical kind a
l
@Joel Denke LayoutDirection | Android Developers shows only horizontal directions
j
Ah ok maybe mixing it up with Row, sorry if thats the case
l
I gave my go at a custom arrangement and came up with this:
Copy code
fun Arrangement.Vertical.reversed(enabled: Boolean): Arrangement.Vertical {
    return object : Arrangement.Vertical {
        override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) {
            with(this@reversed) {
                this@arrange.arrange(totalSize, sizes, outPositions)
            }
            if (enabled) outPositions.reverse()
        }
    }
}
Usage:
Copy code
Column(
    verticalArrangement = Arrangement.Bottom.reversed(isReversed)
)
Edit: Okay, maybe it's not working 😄 I wanted to honor the original Top vs. Bottom arrangement too and only change the order of the children