https://kotlinlang.org logo
#compose
Title
# compose
b

Bradleycorn

03/06/2021, 2:22 PM
If I have a
Column
and I want it's content to be centered (vertically) on the screen, I can do:
Copy code
Column(modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center) { ... }
But what if I don't want it centered vertically, but instead want (the top of) it to be offest 35% from the top of the screen? I can use the
offset
modifier (
offset(y=100.dp)
) to place it a certain amount from the top, but I want to specify the offset by percentage, not dp ...
a

Albert Chang

03/06/2021, 2:35 PM
You can add a
Spacer(modifier = Modifier.fillMaxHeight(fraction = 0.35f))
.
b

Bradleycorn

03/06/2021, 2:35 PM
ah, arrange the items to the "top", and then use the Spacer to push it down .. that would work
b

Bradleycorn

03/06/2021, 2:45 PM
mind blown
@Adam Powell using
placeCenter
as a reference:
Copy code
internal fun placeCenter(totalSize: Int, size: IntArray, outPosition: IntArray) {
        val consumedSize = size.fold(0) { a, b -> a + b }
        var current = (totalSize - consumedSize).toFloat() / 2
        size.forEachIndexed { index, it ->
            outPosition[index] = current.roundToInt()
            current += it.toFloat()
        }
    }
I presume
totalSize
is the size of the container (column) itself,
size
is an array of the sizes of each item in the container, and
outPosition
is an array of positions at which to place each item in the container?
a

Adam Powell

03/06/2021, 3:03 PM
Yep, says as much right in the method docs 🙂
b

Bradleycorn

03/06/2021, 3:23 PM
Copy code
fun Arrangement.fromStart(@FloatRange(from = 0.0, to = 1.0) percent: Float): Arrangement.Horizontal {
    return object: Arrangement.HorizontalOrVertical {
        override val spacing = 0.dp

        override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) {
            place(percent, totalSize, sizes, outPositions)
        }

        override fun Density.arrange(
            totalSize: Int,
            sizes: IntArray,
            layoutDirection: LayoutDirection,
            outPositions: IntArray
        ) {
            when (layoutDirection) {
                LayoutDirection.Ltr -> place(percent, totalSize, sizes, outPositions)
                else -> {
                    sizes.reverse()
                    place(percent, totalSize, sizes, outPositions)
                    outPositions.reverse()
                }
            }
        }


    }
}

fun Arrangement.fromTop(@FloatRange(from = 0.0, to = 1.0) percent: Float): Arrangement.Vertical {
    return object: Arrangement.HorizontalOrVertical {
        override val spacing = 0.dp

        override fun Density.arrange(totalSize: Int, sizes: IntArray, outPositions: IntArray) {
            place(percent, totalSize, sizes, outPositions)
        }

        override fun Density.arrange(
            totalSize: Int,
            sizes: IntArray,
            layoutDirection: LayoutDirection,
            outPositions: IntArray
        ) {
            when (layoutDirection) {
                LayoutDirection.Ltr -> place(percent, totalSize, sizes, outPositions)
                else -> {
                    sizes.reverse()
                    place(percent, totalSize, sizes, outPositions)
                    outPositions.reverse()
                }
            }
        }
    }
}

private fun place(percent: Float, totalSize: Int, size: IntArray, outPosition: IntArray) {
    var current = (totalSize * percent)
    size.forEachIndexed { index, it ->
        outPosition[index] = current.roundToInt()
        current += it.toFloat()
    }
}
@Adam Powell, FTW!
And then ...
Copy code
Column(
    modifier = Modifier.fillMaxSize(), 
    verticalArrangement = Arrangement.percentFromStart(0.35F)) {
 ... 
}
👍 2
a

Adam Powell

03/06/2021, 3:28 PM
Working precisely as intended 🙂
b

Bradleycorn

03/06/2021, 3:28 PM
yall really should make things more difficult 😉
😅 2
I edited the post above and broke it up into 2 more semantically named functions,
fromTop
which returns a
Vertical
and
fromStart
which returns a
Horizontal
in case anyone finds this and wants to use it. That seems to fall in line better with the other functions on
Arrangement
, like
spacedBy
👍 2