Home > Mobile >  TextField overflow and softwrap not working with Compose Constraint Layout
TextField overflow and softwrap not working with Compose Constraint Layout

Time:09-04

I've been trying to build a list with a Card in it formatted like this:

Card Content

The difficulty here is that the title e.g. "Bread" and ingredient name e.g. "Flour" can be very long and thus I want to have an ellipsis to keep things manageable i.e. "My Long Flour name" will be displayed as "My Long Flou..." or as much space as is allowed. The picture size and the gram and percent widths are constant .dp values.

Ellipsis worked fine when it was in a Column but with ConstraintLayout it doesn't seem to work and I get this: enter image description here

here's my code

@Composable
fun BakeItem(
    modifier: Modifier = Modifier,
    bake: Bake,
    cardClicked: () -> Unit,
    ingredeints: List<Ingredient>
) {
    Card(
        modifier = modifier
            .padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp)
            .clickable { cardClicked() }
            .fillMaxSize()
            .wrapContentHeight(),
        border = BorderStroke(4.dp, MaterialTheme.colorScheme.secondary),
        shape = RoundedCornerShape(14.0.dp),
        colors = cardColors(
            containerColor = MaterialTheme.colorScheme.background
        )
    ) {
        val context = LocalContext.current
        val uri = remember(bake.imagePath) { Uri.parse(bake.imagePath) }
        // Card Content

        ConstraintLayout(
            modifier = modifier
                .fillMaxSize()
                .padding(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp)
        ) {
            val (titleRef, gramColRef, ingrColRef, percentColRef,
                imageRef, dateRef, starsRef) = createRefs()

            Text(
                modifier = modifier
                    .padding(4.dp)
                    .constrainAs(titleRef) {
                        top.linkTo(parent.top, margin = 8.dp)
//                        end.linkTo(imageRef.start, margin = 8.dp)
                        start.linkTo(parent.start, margin = 8.dp)
                    }
                    .background(Color(0xffeeeeee)),
//                textAlign = TextAlign.Left,
                text = if (bake.recipeName.isEmpty()) "<Unnamed>" else bake.recipeName,
                style = MaterialTheme.typography.titleLarge,
                fontWeight = FontWeight.Bold,
                color = MaterialTheme.colorScheme.primary,
                softWrap = false,
                overflow = TextOverflow.Ellipsis,

                )

            Column(
                horizontalAlignment = Alignment.End,
                modifier = modifier
                    .width(50.dp)
                    .constrainAs(gramColRef) {
                        top.linkTo(titleRef.bottom, margin = 8.dp)
                        end.linkTo(ingrColRef.start, margin = 8.dp)
                        start.linkTo(parent.start, margin = 8.dp)
                    }
            ) {
                ingredeints.forEachIndexed { _, it ->
                    Text(
                        text = it.weightGram,
                        style = MaterialTheme.typography.titleSmall,
                        softWrap = false,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }
            Column(
                modifier = modifier
                    .constrainAs(ingrColRef) {
                        top.linkTo(titleRef.bottom, margin = 8.dp)
                        start.linkTo(gramColRef.end, margin = 8.dp)
                        end.linkTo(ingrColRef.start, margin = 8.dp)
                    },

                ) {
                ingredeints.forEachIndexed { _, it ->
                    Text(
                        text = it.name,
                        style = MaterialTheme.typography.titleSmall,
                        softWrap = false,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }
            Column(
                modifier = modifier
                    .width(50.dp)
                    .constrainAs(percentColRef) {
                        top.linkTo(titleRef.bottom, margin = 8.dp)
                        end.linkTo(imageRef.start, margin = 8.dp)
                        start.linkTo(ingrColRef.end, margin = 8.dp)
                    },
                horizontalAlignment = Alignment.End
            ) {
                ingredeints.forEachIndexed { i, it ->
                    Text(
                        text = if (i == 0) "" else it.bakingPercent,
                        style = MaterialTheme.typography.titleSmall,
                        softWrap = false,
                        overflow = TextOverflow.Ellipsis
                    )
                }
            }

            Text(
                modifier = modifier.padding(
                    top = 8.dp,
                    start = 4.dp,
                    end = 4.dp,
                    bottom = 4.dp
                ),
                text = bake.notes,
                style = MaterialTheme.typography.titleSmall,
                color = MaterialTheme.colorScheme.onSurface,
                maxLines = 3
            )

            if (bake.imagePath.isNotEmpty()) {
                Image(
                    modifier = modifier
                        .constrainAs(imageRef) {
                            top.linkTo(parent.top, margin = 8.dp)
                            end.linkTo(parent.end, margin = 8.dp)
                        }
                        .padding(4.dp)
                        .requiredSize(150.dp)
                        .clip(RoundedCornerShape(14.dp))
                        .border(
                            4.dp,
                            MaterialTheme.colorScheme.primaryContainer,
                            RoundedCornerShape(14.dp)
                        ),
                    painter = rememberAsyncImagePainter(
                        remember(uri) {
                            ImageRequest.Builder(context)
                                .data(uri)
                                // TODO, think of caching improvements
                                //              .diskCacheKey(uri.toString()   key.value)
                                //              .memoryCacheKey(uri.toString()   key.value)
                                .diskCachePolicy(CachePolicy.DISABLED)
                                .memoryCachePolicy(CachePolicy.DISABLED)
                                .build()
                        }
                    ),
                    contentScale = ContentScale.Crop,
                    contentDescription = "Image of your bake"
                )
            } else {
                Spacer(modifier = modifier
                    .background(Color.Blue)
                    .width(150.dp)
                    .height(10.dp)
                    .constrainAs(imageRef) {
                        top.linkTo(parent.top, margin = 8.dp)
                        end.linkTo(parent.end, margin = 8.dp)
                    })
            }

            Text(
                modifier = modifier
                    .padding(4.dp)
                    .constrainAs(dateRef) {
                        bottom.linkTo(parent.bottom, margin = 8.dp)
                        top.linkTo(imageRef.bottom, margin = 8.dp)
                        end.linkTo(parent.end, margin = 8.dp)
                    },
                text = bake.startTime.toString(),
                style = MaterialTheme.typography.titleMedium,
                color = MaterialTheme.colorScheme.onSurface,
//                    textAlign = Layout.Alignment.ALIGN_CENTER
            )

            createHorizontalChain(
                gramColRef, ingrColRef, percentColRef, imageRef,
                chainStyle = ChainStyle.SpreadInside
            )
            createVerticalChain(
                imageRef, dateRef,
                chainStyle = ChainStyle.SpreadInside
            )
            createHorizontalChain(
                titleRef, imageRef,
                chainStyle = ChainStyle.SpreadInside
            )
        }
    }
}

CodePudding user response:

In the title you have to add as constrain width = Dimension.fillToConstraints, end.linkTo(imageRef.start, margin = 8.dp) and maxLines = 1:

Text(
    modifier = Modifier
        .padding(4.dp)
        .constrainAs(titleRef) {
            top.linkTo(parent.top, margin = 8.dp)
            end.linkTo(imageRef.start, margin = 8.dp)
            start.linkTo(parent.start, margin = 8.dp)
            width = Dimension.fillToConstraints
        }
        .background(Color(0xffeeeeee)),
    text = "Recipe Name",
    //...
    maxLines = 1,
    overflow = TextOverflow.Ellipsis,
)

For the list instead of using 3 Columns you do can something different.
For the ingredient name add the weight(1f) modifier and the maxLines = 1

        Column(
            modifier = Modifier
                .constrainAs(listRef) {
                    top.linkTo(titleRef.bottom, margin = 8.dp)
                    end.linkTo(imageRef.start, margin = 8.dp)
                    start.linkTo(parent.start, margin = 8.dp)
                    width = Dimension.fillToConstraints
                }
        ) {
            //forEach Row...

            Row(Modifier.fillMaxWidth()) {
                Text(text = "50g", Modifier.width(xx.dp), textAlign = TextAlign.End)

                Text(
                    text = "Very long text long text",
                    Modifier
                        .padding(start=4.dp)
                        .weight(1f),   
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )
                Text(text = "75%", Modifier.width(xx.dp), textAlign = TextAlign.End)
            }
        }

enter image description here

  • Related