Lavmee / constraintlayout-compose-multiplatform

Useful when implementing larger layouts with more complicated alignment requirements.
Apache License 2.0
160 stars 5 forks source link

Text draws over each other instead of ellipsizing #76

Open ShmuelCammebys opened 2 months ago

ShmuelCammebys commented 2 months ago

In AndroidX ConstraintLayout, when a TextView is constrained e.g. to the start and end of the parent, and the parent shrinks, if the TextView is configured properly, it will ellipsize. A similar behavior is observed in a ChipGroup. However, this implementation of ConstraintLayout doesn't respect that, so composables are drawn over each other.

@Composable
fun ConversationListItem(
    conversation: Conversation,
    onMoreOptionsClicked: () -> Unit
) {

    ConstraintLayout(
        Modifier.clickable {

        }
    ) {
        val (avatarGroup, title, lastMessage, participants, iconButton, timestamp, divider) = createRefs()

        Box(Modifier.constrainAs(avatarGroup) {
            start.linkTo(parent.start, margin = 8.dp)
        }) {
            AvatarGroup(conversation.participants)
        }
        val titleConstraint = Modifier.constrainAs(title) {
            start.linkTo(avatarGroup.end, margin = 4.dp)
            top.linkTo(parent.top)
        }
        ChipGroup(modifier = titleConstraint) { //could implement as two separate constraints, but this is effectively a Row that wraps like a Text if its children can't fit on the same line given the remaining width
            if (conversation.isUnread)
                Text(
                    conversation.title,
                    fontSize = 14.sp,
                    lineHeight = 23.sp,
                    fontWeight = FontWeight.ExtraBold,
                    color = blueHighlight
                )
            else
                Text(
                    conversation.title,
                    fontSize = 14.sp,
                    lineHeight = 23.sp,
                )
            Row {
                if (conversation.isNotificationsMuted) Icon(
                    Icons.Default.NotificationsOff,
                    "Muted"
                )
                if (conversation.isFavorite) Icon(
                    Icons.Default.Star,
                    "Favorited"
                )
            }
        }

        Text(
            getTimeSince(conversation.dateUpdated),
            Modifier.constrainAs(timestamp) {
                end.linkTo(parent.end, margin = 8.dp)
                top.linkTo(parent.top)
            },
            fontWeight = FontWeight.ExtraLight
        )
        Text(
            conversation.lastMessage.message,
            Modifier.constrainAs(lastMessage) {
                top.linkTo(title.bottom)
                start.linkTo(avatarGroup.end)
//                end.linkTo(iconButton.start, margin = 36.dp) //won't ellipsize 36 dp before icon
            },
            fontSize = 14.sp,
            lineHeight = 23.sp,
            fontWeight = FontWeight.Light,
            overflow = TextOverflow.Ellipsis,
            maxLines = 1
        )
        Text(
            conversation.participants.joinToString { it.name },
            Modifier.constrainAs(participants) {
                top.linkTo(lastMessage.bottom)
                start.linkTo(avatarGroup.end)
            },
            fontSize = 14.sp,
            lineHeight = 23.sp,
            overflow = TextOverflow.Ellipsis,
            maxLines = 1
        )
        IconButton(
            onMoreOptionsClicked,
            Modifier.constrainAs(iconButton) {
                top.linkTo(timestamp.bottom)
                end.linkTo(parent.end)
            }
        ) {
            Icon(Icons.Default.MoreVert, "More options")
        }
        HorizontalDivider(Modifier.constrainAs(divider) {
            bottom.linkTo(parent.bottom)
            start.linkTo(parent.start)
            end.linkTo(parent.end)
        })
    }

}