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

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

Related

Kotlin Jetpack compose Center text in Column inside a LazyColum

I'am new to jetpack compose and i really liked it. But ran into a problem : I want to create a card and inside of it, i would like to display a list of item with divider between them. I was almost able to achieved it here is my code :
Box(modifier = Modifier.background(Color(0xFFf4f4f4))
.fillMaxSize()
.padding(top = 20.dp)) {
Card(
modifier = Modifier
.fillMaxWidth(),
shape = RoundedCornerShape(20.dp),
elevation = 5.dp
) {
val colorNamesList = listOf("Red", "Green", "Blue", "Indigo")
LazyColumn() {
itemsIndexed(
colorNamesList,
) { index, item ->
Column(
modifier = Modifier
.background(
color = Color(0xFFf2f2f2),
)
.clickable {
println(item)
},
horizontalAlignment = Alignment.CenterHorizontally,//those 2 does nothing
verticalArrangement = Arrangement.Center //when i change it nothing change
) {
println(item + index)
Text(
text = "Item at $item",
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
//textAlign = TextAlign.Center, without it image 1, with it image 2
color = Color.Black,
)
if (index < colorNamesList.lastIndex) {
Divider(
color = Color.Black.copy(alpha = 0.2f),
modifier = Modifier
.padding(horizontal = 80.dp),
)
}
}
}
}
}
}
It's almost good but i didn't managed to align the text inside it, i searched some answer but Alignment and Arrangement doesn't change anything in my situation.
I was able to align horizontally by adding textAlign = TextAlign.Center as i commented in my code but, i couldn't align vertically, the text stay on the top of his cell :
What i want to do is text center in every cell of the column. Thanks for the help.
You can achieve this by adding similar xml attribute like "wrap_content" as height in compose too.
Add "wrapContentHeight()" to modifier and you will get it to align to centre of the page.
Text(
text = "Item at $item",
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.wrapContentHeight(),
textAlign = TextAlign.Center
color = Color.Black,
)

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,
)

Row with two Text in Constraint fashion in Jetpack Compose

I want to include two Text in a Row where the first Text's width is upto the start of 2nd Text, like this
I am trying Modifier weight but the result achieved is not the same.
Is there a way to do it by using Row itself and not ConstraintLayout.
EDIT :
Row(modifier = Modifier.fillMaxWidth()) {
Text(
"Some long title abcd efgh ijkl mnop qrst uvwx yzzzzz Some long title abcd efgh ijkl mnop qrst uvwx yzzzzz",
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(5f)
)
Text("View all", modifier = Modifier.weight(1f))
}
This works, please suggest a better solution if I am missing something.
EDIT 2 :
Its giving me results like this:
I want the Title to start from the beginning of Row
You can use something like:
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween) {
Text(
"Short title",
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f)
)
Text("View all")
}
Just for comparison, this is the same solution but done with ConstraintLayout:
ConstraintLayout(
modifier = Modifier.fillMaxSize()
) {
val (title, viewAll) = createRefs()
Text(text = "View all", Modifier
.background(Color.Green)
.constrainAs(viewAll) {
top.linkTo(parent.top, 8.dp)
end.linkTo(parent.end, 8.dp)
})
Text(text = "Short title",
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.background(Color.White)
.constrainAs(title) {
top.linkTo(parent.top, 8.dp)
start.linkTo(parent.start, 8.dp)
end.linkTo(viewAll.start, 8.dp)
width = Dimension.fillToConstraints
})
}

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

Jetpack Compose How to Align text or content of Text component with specific size to bottom left or right?

How can i align text to bottom section of a Text component with Jetpack Compose? TextAlign only has Start, End, Left, Center, Right and Justify options.
Text(
text = "First",
textAlign = TextAlign.Start,
modifier = Modifier
.background(Color(0xFF1976D2))
.size(200.dp),
color = Color.White,
)
I want to align Text component's content, each Text has a specific size using modifier.size(x), to align their text to bottom. In the image blue rectangles are Text with different sizes should align the text inside them like in classic Android done with android:gravity.
It is similar to textAlign = TextAlign.x but for bottom.
Setting alignment from a Box aligns Text inside Box or Modifier.align(Alignment.BottomEnd) in BoxScope does what android:layout_gravity does for views, aligns the Text component, not the content of Text component, you can see the difference here.
Code for the blue rectangles in the image is
#Composable
fun BoxExample() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.background(Color.LightGray)
) {
// This is the one at the bottom
Text(
text = "First",
modifier = Modifier
.background(Color(0xFF1976D2))
.size(200.dp),
color = Color.White,
)
// This is the one in the middle
Text(
text = "Second",
modifier = Modifier
.background(Color(0xFF2196F3))
.size(150.dp),
color = Color.White
)
// This is the one on top
Text(
text = "Third ",
modifier = Modifier
.background(Color(0xFF64B5F6))
.size(100.dp),
color = Color.White
)
}
}
For orange rectangles
#Composable
fun BoxShadowAndAlignmentExample() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.background(Color.LightGray)
.padding(8.dp)
) {
Box(
modifier = Modifier.shadow(
elevation = 4.dp,
shape = RoundedCornerShape(8.dp)
)
) {
// This is the one at the bottom
Text(
text = "First",
modifier = Modifier
.background(Color(0xFFFFA000))
.size(200.dp),
color = Color.White
)
}
Box(
modifier = Modifier.shadow(
elevation = 4.dp,
shape = RoundedCornerShape(8.dp)
)
.align(Alignment.TopEnd)
) {
// This is the one in the middle
Text(
text = "Second",
modifier = Modifier
.background(Color(0xFFFFC107))
.size(150.dp),
color = Color.White
)
}
val modifier = Modifier.shadow(
elevation = 4.dp,
shape = RoundedCornerShape(8.dp)
)
.align(Alignment.BottomStart)
Box(
modifier = modifier
) {
// This is the one on top
Text(
text = "Third ",
modifier = Modifier
.background(Color(0xFFFFD54F))
.size(100.dp),
color = Color.White
)
}
}
}
Using align modifier you can align child components in specific positions relative to their parents:
Box(modifier = Modifier.fillMaxSize()) {
Text(modifier = Modifier.align(Alignment.BottomEnd),text = "Aligned to bottom end")
Text(modifier = Modifier.align(Alignment.BottomStart),text = "Aligned to bottom start")
Text(modifier = Modifier.align(Alignment.CenterStart),text = "Aligned to start center ")
Text(modifier = Modifier.align(Alignment.TopCenter),text = "Aligned to top center ")
}
Say your component is a Box, place your text within the Box like this:
Box(
modifier = Modifier.fillMaxSize(),
Alignment.BottomStart
) {
Text(
"First",
Modifier.padding(16.dp),
)
}
Basically, you define the section of the component that you want to use in that component, not in the text.
2 years later and I think I have the actual solution for this issue:
for your text composable, add this modifier:
.wrapContentHeight() and for the parameter, you may for example align it to the bottom with Alignment.Bottom
you can try with:
Text(
modifier = Modifier
.height(150.dp)
.wrapContentHeight(Alignment.Bottom)
,
text = "whooopla",
)

Categories

Resources