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

Fudge

07/15/2020, 8:43 PM
I feel like I'm missing something, is there no way to align a child of a Column to the end of the column? The
gravity
modifier only allows aligning horizontally, but not vertically (and also can only be called when a Column is in scope which is very odd, I mean what do you do when the column is way up the tree?)
Here's a workaround for accomplishing this seemingly simple thing, I guess:
Copy code
Column(modifier = Modifier.fillMaxHeight()) {
   Row(modifier = Modifier.fillMaxHeight()) {
      child(modifier = Modifier.gravity(Alignment.Bottom))
   }
}
(I would have expected it to look like this:)
Copy code
Column(modifier = Modifier.fillMaxHeight()) {
      child(modifier = Modifier.align(Alignment.Bottom))
}
n

nglauber

07/15/2020, 9:14 PM
What the design do you want to achieve? Depending on your needs, you can use `verticalArrangement`…
Copy code
Column(modifier = Modifier.fillMaxHeight(),
    verticalArrangement=Arrangement.Bottom) {
    Text("AAA")
}
If you have more components… You can use something like this
Copy code
Column(modifier = Modifier.fillMaxHeight()) {
    Text("AAA")
    Text("BBB")
    Spacer(modifier = Modifier.weight(1f))
    Text("CCC")
}
👍 1
f

Fudge

07/15/2020, 9:18 PM
oh, I see, that's one way of doing it
the latter is what I was looking for
👍 1
What about if a
Column
is not in scope? I guess pass Column as a receiver ?
Or ColumnScope rather
n

nglauber

07/15/2020, 9:27 PM
Sorry, I don’t know how to answer that… Do you want to align an item inside of Column but without the Column? What I would do is:
Copy code
Column {
  SomeComponent()
  Spacer(modifier = Modifier.weight(1f))
  YourComponentThatNeedsAlignmentHere()
}
f

Fudge

07/15/2020, 9:49 PM
what I mean is something like this
Copy code
Column {
   Text("bar")
   AlignmentLogicComponent()
}

@Composable fun AlignmentLogicComponent() {
  Spacer(modifier = Modifier.weight(1f)
  Text("foo")
}
I would solve by doing
Copy code
Column {
   Text("bar")
   AlignmentLogicComponent()
}

@Composable fun ColumnScope.AlignmentLogicComponent() {
  Spacer(modifier = Modifier.weight(1f)
  Text("foo")
}
👍 2
z

Zach Klippenstein (he/him) [MOD]

07/15/2020, 10:02 PM
Yes, passing
ColumnScope
as a receiver is the way to do that
a

Adam Powell

07/15/2020, 10:12 PM
it makes me happy to read this thread and see you all having arrived at these solutions 😄
propagating the
ColumnScope
as a receiver to express the required context of where a composable will behave as expected is something I've been pretty excited about, since it addresses the long-standing type safety issues around view xml LayoutParams
so many developer hours wasted wondering why
android:layout_weight
isn't working because the parent changed in some refactor somewhere
1
another way to do this is to have the last item do
Modifier.fillMaxHeight().wrapContentHeight(Alignment.Bottom)
instead of using the weighted spacer; dropping the fillMaxHeight from that will also let you only fill up until the min height is met if that's useful in the situation
n

nglauber

07/16/2020, 12:26 AM
If I understand correctly, you’re creating an extension function for
ColumnScope
, right? In this case you’ll be able to use
AlignmentLogicComponent
inside of all
Column
which I’m not sure it’s an expected behavior… I like the idea though 🙂 Your solution sounds better @Adam Powell (I can’t figure out why 😛)
a

Adam Powell

07/16/2020, 1:59 AM
Not sure what you're asking. The modifier snippet above doesn't use any other receiver scoping
Or do you mean writing a composable function as an extension of ColumnScope? That makes that composable function only valid in a Column, yes.
n

nglauber

07/16/2020, 2:39 AM
Sorry… I didn’t make myself clear… I mean that create a composable function as an extension function of ColumnScope just to allow this component to be aligned correctly inside of a Column sounds strange to me (not saying that’s a bad solution). I think it’s more elegant use the modifier as you shown above.
2 Views