How can I truncate of a Text displayed in Row in Jetpack Compose? - android

I display a text on the left of a row, and display tool buttons on the right of the row with Code A.
It's Ok when the text is short, you can see Image A as I expected.
But when the text is long, I find some tool buttons on the right of the row disappeared, you can see Image B.
I hope that tool buttons on the right of the row can be always displayed, and the left text can be truncated automatically when the sapce is not enough.
How can I do ? Thank!
Code A
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically
) {
Text("This a short text")
//Text("This a very long text text text text text text text text")
Spacer(Modifier.weight(1f))
val iconModifier = Modifier.size(24.dp)
IconButton(
enabled = true,
onClick = {
}
) {
Icon(Icons.Filled.Edit , null, modifier = iconModifier)
}
IconButton(
enabled = true,
onClick = {
}
) {
Icon(Icons.Filled.Delete , null, modifier = iconModifier)
}
IconButton(
enabled = true,
onClick = {
}
) {
Icon(Icons.Filled.ExpandMore , null, modifier = iconModifier)
}
}
Image A
Image B

Apply to the Text the weight modifier and remove the Spacer:
Text("This a very long text text text text text text text text",
modifier = Modifier.weight(1f),
overflow= TextOverflow.Ellipsis,
maxLines = 1)
//Spacer(Modifier.weight(1f))

Related

Show Icon at Right Side and Ellipsis Middle Text If Overflow In Compose

I want two behavior.
[Working] If middle text is short, then heart icon should be next to middle text and cart should be at end,
see image.
[Not working] If middle text is large, then heart icon should stick beside carts left and middle text be ellipsis.
Note: I have tried Modifier.weight(1f,fill = false) for second behaviour but then first broke.
code
Row(
modifier = Modifier.fillMaxSize()
) {
Row(
modifier = Modifier.wrapContentWidth()
) {
Icon(Icons.Filled.Search,"")
Spacer(modifier = Modifier.width(18.dp))
Icon(Icons.Filled.Add,"")
Spacer(modifier = Modifier.width(12.dp))
Text(
text = "If text is long, then cart icon show at end with ellipsis text",
maxLines = 1,
modifier = Modifier
.weight(1f,fill = false)
)
Spacer(modifier = Modifier.width(12.dp))
Icon(Icons.Filled.Favorite,"")
}
Row(Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End) {
Icon(Icons.Filled.ShoppingCart,"")
}
}
You can wrap the Text and the Favorite Icon with a Row and apply to it the weight modifier to fill the available space.
Then assign weight(1f, fill = false) to the Text:
Row(
modifier = Modifier.fillMaxWidth().background(Color.Yellow),
) {
Icon(Icons.Filled.Search,"")
Spacer(modifier = Modifier.width(18.dp))
Icon(Icons.Filled.Add,"")
Row(Modifier.weight(1f)) {
Text(
text = "If text is",
maxLines = 1,
modifier = Modifier
.weight(1f, fill = false)
.padding(8.dp),
overflow = TextOverflow . Ellipsis
)
Icon(
Icons.Filled.Favorite, "",
)
}
Icon(Icons.Filled.ShoppingCart,"")
}
You center component should use the "left space" with weight attribute
modifier = Modifier
.weight(1f)
.padding(8.dp),
overflow = TextOverflow.Ellipsis

How ellipsis only middle text in Android Compose?

I am developing an android app using the jetpack compose.
I want to make a UI like:
Row(
horizontalArrangement = Arrangement.SpaceBetween
) {
Row(
modifier = Modifier.weight(1F)
) {
Text(
text = name,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "($count)",
maxLines = 1,
)
}
Spacer(modifier = Modifier.width(16.dp))
Text(
text = timeText,
)
}
But actually it shows like:
the count information (1) is cut.
How can I show the count information and ellipsis the name text?
Should I use the compose-constraintlayout?
In such cases Modifier.weight should be used on the view, in this case it'll be measured after other siblings:
The parent will divide the vertical space remaining after measuring unweighted child elements and distribute it according to this weight.
If you don't need the view to take all the space available, add fill = false parameter.
Text(
text = name,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f, fill = false)
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = "($count)",
maxLines = 1,
)

Always display placeholder and RTL input in TextField with Jetpack Compose

I want the placeholder not to disappear if I start typing in a field and it should be on the left side of the screen.
But the text input and cursor must be on the right.
An example is in the screenshot. Thanks!
Not the best solution, but it works.
Customizing the placeholder as per the requirement is not possible at this point in time. You have to create a completely customized TextField if that is an absolute requirement.
Note.
This is not a placeholder.
The positioning of the text is absolute, it should be adjusted according to the TextField size.
#Composable
fun FixedPlaceholder() {
var name by remember { mutableStateOf("") }
Box {
OutlinedTextField(
shape = MaterialTheme.shapes.medium,
value = name,
onValueChange = {
name = it
},
singleLine = true,
textStyle = LocalTextStyle.current.copy(
textAlign = TextAlign.End,
),
modifier = Modifier
.fillMaxWidth()
.padding(
horizontal = 16.dp,
vertical = 8.dp,
),
)
Text(
text = "to",
modifier = Modifier
.fillMaxWidth()
.padding(
start = 32.dp,
end = 32.dp,
top = 24.dp,
bottom = 8.dp
),
)
}
}
You don't need the placeholder, just set the leadingIcon property to:
leadingIcon={Text(text="To")}
In Compose, leadingIcon is a composable, and you can set it to anything you like.

Increase space between title and text of AlertDialog in Compose

In a simple AlertDialog like the following
AlertDialog(
modifier = Modifier,
title = {
Text(text = "Title")
},
text = {
Column(
modifier = Modifier.fillMaxWidth()
) {
TextButton() {
Text("Text 1")
}
TextButton() {
Text("Text 2")
}
}
},
confirmButton = {},
dismissButton = {}
)
how can I set a spacing between title and the first TextButton?
I tried to set a .padding(top = X.dp) to the Column, or the first text button, but this seems to only create a space at the bottom of the AlertDialog.
Also setting a custom .height(X.dp) did not work.
I'm using Compose 1.0.3
As #Abhimanyu perfectly explains why it's not working right now, here's the workaround I'm using to achieve the desired padding: putting the title in the content. AlertDialog's title param is optional, so it can be omitted/set to null, and instead the actual title can be put in the text parameter (which holds the dialog content).
#Composable
fun MyComposable() {
AlertDialog(
title = null,
text = {
Column {
Text(
modifier = Modifier.padding(vertical = 16.dp),
text = "Actual title"
)
// Rest of the dialog content
}
}
)
}
This is NOT an answer. It only provides info on why this is not possible.
The requirement seems not achievable at this point (6th Oct 2021) with the current compose version (1.0.3).
Will update this once that is possible.
The AlertDialog code does not respect the padding values provided.
AlertDialog.kt
// Baseline distance from the first line of the text to the last line of the title
private val TextBaselineDistanceFromTitle = 36.sp
The text offset used for the positioning is calculated like this.
val textOffset = if (titlePlaceable == null) {
TextBaselineDistanceFromTop.roundToPx()
} else {
TextBaselineDistanceFromTitle.roundToPx()
}
The distance between the first text in the text composable and the last text in the title composable is always 36.sp.
The Alert Dialog code in compose seems too hackish currently and I could see a few TODO's in the code.
Hopefully, the code will be changed to handle more scenarios soon.
I'm using this composable as first child inside Column
#Composable
fun HackySpacer(space: Dp) {
Box(
modifier = Modifier
.height(space)
.fillMaxWidth()
) {
Text(text = "")
}
}
It's not perfect, but it works for my usecase.
Is now possible using the new AlertDialog from Compose Material 3.
The default spacing between title and text is much more reasonable and it is also possible to add Modifier.padding() or Spacer() to both.
implementation("androidx.compose.material3:material3:1.0.0-alpha01")
androidx.compose.material3.AlertDialog(
onDismissRequest = {
openDialog.value = false
},
title = {
Text(text = "Title", modifier = Modifier.padding(50.dp))
},
text = {
Spacer(Modifier.height(50.dp))
Text(text = "Turned on by default")
},
confirmButton = {
TextButton(
onClick = {
openDialog.value = false
}
) {
Text("Confirm")
}
},
dismissButton = {
TextButton(
onClick = {
openDialog.value = false
}
) {
Text("Dismiss")
}
}
)

How can I align an Icon to top of Text?

This is how I want this to look like
Notice that the text is always a number.
How can I align the top of the Heart to the red line (top of text)?
If I can remove the font padding (over the red line and below the number) this also could work for me fine but I do not know how to do this.
This is my code
Row {
Text(
pulse.toString(),
modifier = Modifier
.background(Color.Gray),
fontSize = 60.sp,
color = vitalModifier.color)
Spacer(modifier = Modifier.width(10.dp))
Icon(
modifier = Modifier
.background(Color.Green)
.alignBy(LastBaseline),
painter = painterResource(R.drawable.ic_heart),
contentDescription = null,
tint = vitalModifier.color)
}
You can use BadgedBox to achieve this
BadgedBox(badge = { Badge { Text("8") } }) {
Icon(
Icons.Filled.Favorite,
contentDescription = "Favorite"
)
}
https://dev.to/farhanroy/jetpack-compose-badge-18ho

Categories

Resources