What has replaced weights? - android

Trying to figure out how to position items in the latest build... Many examples online indicate to use modifier = Modifier.weight(...), but the option is simply not given as of the build I'm using.
I need to send a button at the bottom of the page regardless of the size of a lazy column just above it. What's the preferred way to do such a thing?

With 1.0.0-beta02 the Modifier.weight exists.
Size the element's height proportional to its weight relative to other weighted sibling elements in the Column. The parent will divide the vertical space remaining after measuring unweighted child elements and distribute it according to this weight
Something like:
val itemsList = (0..60).toList()
Column {
LazyColumn(modifier = Modifier.weight(1f)){
items(itemsList) {
Text("Item is $it")
}
}
Row( verticalAlignment = Alignment.Bottom) {
Text(text = "Footer row")
}
}
Otherwise you can use a ConstraintLayout.

Related

Adjust content to scrollable row width in jetpack compose

I have a Row with an horizontal scroll and n items inside of varying and unknown widths.
Case 1 -> In case the items dont fill the container's width I want the last item to fill the remaining space.
Case 2 -> In case the items sum of widths is higher than the containers width (hence allowing scroll), I want the last item to behave like all the others.
I have tried to use .fillMaxWidth in the last item but inside a scrollable row this has zero effect.
I can use .weight(1f) for Case 1, but this ruins the UI in Case 2.
I know a solution could be calculating manually the width of each item, and switch the modifier from adding the weight modifier to not using it as soon as the widths exceed the container's width but I believe there might be a solution using Modifier functions inside the Row? Or possibly with a Lazy Row?
Sample code:
val horizontalScroll = rememberScrollState()
Row(
Modifier
.fillMaxWidth()
.horizontalScroll(horizontalScroll)
) {
items.forEachIndexed { index, item ->
ItemComponent(
modifier = if (index == items.lastIndex) Modifier.weight(1f) else Modifier
text = item.text
)
}
}

Jetpack Compose Text having extra padding when wrapping to next line

I have a a text element with an icon to its right, both wrapped in a Row. The text has a 1.0f weight with fill = false. When a word wraps to the next line, the text has some padding at the end of it causing the icon to be too far apart from it. This is what it looks like:
App Example
Here is the code:
Row(
modifier = Modifier.width(150.dp)
) {
Text(
"John Doe John Doe John Doe",
modifier = Modifier.weight(1.0f, fill = false).background(Color.Green)
)
Icon(
imageVector = Icons.Default.Done,
contentDescription = "",
)
}
How do I make it so the text's width wraps itself without adding that extra spacing?
This is a normal behavior. It happens because you set weight for your Text and a width modifier for your Row.
It's kind of unavoidable when setting a specific width or height. It may happen even if you set weight for both Composables inside the Row (0.1f and 0.9f). Because the word can't fit in the remaining space but the Composable must fill the Row
You set the row width to 150.dp and when your Text has a weight modifier, it fills the row even if a word in your Text composable doesn't fit in the line.

Set max constraint width to compose widget placed between other fix sized widgets

I'm trying to make a layout like on the scheme below:
I've already found a solution with a weighted Row() inside other Row(). But it looks too complicated for such a simple problem.
Row() {
Icon() // Fix width
Row(modifier = Modifier.weight(1f)) {
Text(modifier = Modifier.weight(1f)) // Max width
Icon() // Fix width
}
}
Surely many have faced such an issue. Are there more beautiful ways to solve it?
You need not use a nested Row here. Just give the weight(1f) modifier to center element.
Row {
Icon() // View 1 (Fix width)
CenterPiece(
modifier = Modifier
.weight(1f)
.padding(horizontal = 8.dp) // For the spacing between components
)
Icon() // View 3 (Fix width)
}
You might also want to add verticalAlignment = Alignment.CenterVertically to the Row so that the three components are centered vertically.

How do I expand the full height of a lazy column in Jetpack Compose?

I have a Lazy column like so
LazyColumn(
modifier = Modifier
.fillMaxWidth()
.height(gridMultiple(i = 15) * data.size)
.padding(vertical = gridMultiple(i = 2)),
verticalArrangement = Arrangement.spacedBy(gridMultiple(i = 2)),
userScrollEnabled = false
) {
items(data.size) { index ->
val item = data[index]
ListItem(
item,
editButtonClick = { id -> onEditClick(id) }
)
}
}
and it is encapsulated in an interop composable XML element like so:
<androidx.compose.ui.platform.ComposeView
android:id="#+id/informationList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
The catch is that the informationList is inside of a ScrollView (XML), and I want the lazy column list to be fully expanded within the scroll view. But I do not know the height that the elements need to be, so I am doing this math here:
.height(gridMultiple(i = 15) * data.size)
But it uses either too much space or not enough. So either elements get cut off, or they have a lot of empty space at the end. I want to use exactly as much space as the LazyColumn needs. If I set the height to be wrapping, I get an exception that the lazy column has an infinite possible height and must have a height specified. There must be a way to do this. I know that the max amount of elements that can ever be in the lazy column is limited to about 10.
That will defeat the whole purpose of LazyColumn. The lazy part just won't work when you use it like that. You could just go with normal Column and it would make no difference at all in terms of performance. Especially with 10 items, with such number the LazyColumn is huge overkill. Bonus for your case - Column supports wrapContentHeight().
TLDL - just use Column with wrapContentHeight() and it should be just fine

Offset an item taking its height into account in Jetpack Compose

I want to position my own component (say a Text component) vertically so that I can specify the y-offset relative to the bottom of the Text component. How could I do this in Jetpack compose?
So something like
Column {
Text("Something", modifier = Modifier.offset(y=10.dp))
}
But instead of 10dp representing the top y-position of the Text component it would be the bottom y-position. Basically taking into account the height of the Text even if Text size changes. So y = offset.y - height
As I can see it, there's two problems:
The font size can be changed, so I cannot hard code the text height.
I need to know the size of my Text component during composition, but I don't know how to get that.
You could go for custom Composables,
#Composable
fun CustomText(y: Dp){
Layout(content = { Text(text = "Lorem Ipsum") }){measurables, constraints ->
val text = measurables[0].measure(constraints)
layout(constraints.maxWidth, constraints.maxHeight){ //Change these per your needs
text.placeRelative(IntOffset(0, y.value.roundToInt() - text.height))
}
}
}
You could also use a custom Modifier. Check out using the layout modifier

Categories

Resources