I’m creating an app to studies and I got an "error".
I looked for help and saw some posts here and on another sites, but nothing works to me.
The last item from a Composable Row is going off the width view when the body text is "larger", as you can see here. I can click in the item, but it’s invisible:
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.Checkbox
import androidx.compose.material3.ElevatedCard
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.cleanarchtodo.ui.theme.CleanArchToDoTheme
@Composable
fun ToDoCard(
modifier: Modifier = Modifier,
text: String = "",
checked: Boolean = false,
onCheckedChange: () -> Unit,
) {
ElevatedCard(
modifier = modifier
.fillMaxWidth()
.padding(
vertical = 4.dp,
horizontal = 12.dp
),
elevation = CardDefaults.cardElevation(
defaultElevation = 8.dp
)
) {
Row(modifier = Modifier
.fillMaxWidth(),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.Start
) {
Checkbox(
checked = checked,
onCheckedChange = { onCheckedChange() }
)
Text(
text = text,
fontSize = 20.sp,
maxLines = 3,
overflow = TextOverflow.Ellipsis
)
Spacer(modifier = Modifier.weight(1f))
IconButton(
onClick = { }
) {
Icon(
imageVector = Icons.Default.Delete,
contentDescription = "Delete ToDo"
)
}
}
}
}
@Preview(
showBackground = true
)
@Composable
fun PreviewToDoCard() {
CleanArchToDoTheme {
ToDoCard(
text = "Buy bananas Buy bananas Buy bananas",
onCheckedChange = {}
)
}
}
Somebody can help me?
2
Answers
It happens because
Row
andColumn
when measuring composables uses total space – space used by other children. SinceText
can be measured with whole remaining spaceIconButton
gets 0 maxWidth to be measured between 0 and maxWidth it gets 0 width.Solution is to use
Modifier.weight(1f, fill = false)
to measureText
last. Composables with weight are measured after other Composables. But since you usedSpacer
with Modifier.weight space will be divided equally.For that you can change it like this.
By changing as above Row first measures
IconButton
then inner Row is measured since Spacer used inside it wit fill when Text is smaller it increases width to match outer Row.Text
widget grows in size to accomodate the size of the text inside it, until it runs out of the parent width. With a very long text like in your case, no space is left for the button to the rightTo fix this, you can add
Modifier.weight(1f)
to your Text, so it takes up all free space, but is laid out after all other elements, including the button. Also with this approach, you can drop theSpacer(Modifier.weight(1f)
after theText
, because the newText
basically combines these two functions