How ellipsis only middle text in Android Compose? - android

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

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 to put Text composables in Row, one with a mutable width

I want to know the way to put Text composables in Row, one with a mutable width for a TopAppBar.
Regarding the two Texts, one has a width that varies with the number of characters, and the other has a fixed number of characters and we want the string to be displayed reliably.
I tried writing codes to make that, but it did not work as I had expected.
Here is my codes and a image of what I thought.
#Composable
fun AppBarTestScreen() {
Column {
TopAppBar(
title = {
Row(Modifier.fillMaxWidth()) {
Text(
text = "〇〇〇〇〇〇",
modifier = Modifier.wrapContentWidth().widthIn(max = 210.dp),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
softWrap = false
)
Text(
text = "'s Attribute",
modifier = Modifier.fillMaxWidth().clipToBounds(),
textAlign = TextAlign.Start,
overflow = TextOverflow.Clip,
softWrap = false
)
}
}
)
....
}
}
I tried a variety of Modifier functions and patterns
For now, I set a maximum width on the first Text. However, this works well when the device is in portrait orientation, but not in landscape orientation. Furthermore, the results are not clear when it comes to tablets and other devices.
If there is no other way, I will eventually have to rely on unstable external libraries, but is there any way to make what I want without them?
Apply the weight modifier to the 1st Text:
Row(Modifier.fillMaxWidth()) {
Text(
text = "〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇〇",
modifier = Modifier.weight(1f),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(text = "'s Attribute")
}
If you want to avoid to fill the whole space with the 1st Text use Modifier.weight(1f,false):
Text(
text = "〇〇〇〇〇〇〇",
modifier = Modifier.weight(1f,false),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)

How to remove padding in text line on Jetpack Compose

I faced with a problem related to Text element in Jetpack Compose. I wanted to place two separated Text elements under each other but I can't remove their inner paddings to make them look like not so separated.
As you can see on pic below Text with "02" has these paddings. Is there any way to crop them?
I tried to use .offset() and .height() modifiers to change the Text box size, but it looks like a really awful solution.
Code example to reproduce:
Box(
modifier = Modifier
.height(65.dp)
.width(65.dp)
.background(Color.White)
) {
Column(
modifier = Modifier
.align(Alignment.Center)
) {
Text(
text = "00",
maxLines = 1,
overflow = TextOverflow.Clip,
style = MaterialTheme.typography.h5.copy(
fontWeight = FontWeight.SemiBold
),
color = Color.Black,
modifier = Modifier
.align(Alignment.CenterHorizontally)
)
Text(
text = "Text",
style = MaterialTheme.typography.body2,
color = Color.Gray,
modifier = Modifier.align(Alignment.CenterHorizontally)
)
}
}
Thanks in advance!

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.

Jetpack Compose Textfield Label not staying in center

I'm trying to make a textfield thats quite small (32.dp). When doing this, the label gets pushed to the bottom and I can't find a way to keep it centered? I've tried using TextAlign.center but no luck
TextField(
modifier = Modifier
.height(32.dp)
.padding(horizontal = 8.dp)
.border(1.dp, colorResource(id = R.color.mono4), RoundedCornerShape(32.dp))
.constrainAs(commentBox) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(profilePhoto.end)
end.linkTo(postText.start)
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
},
label = {
Text(
textAlign = TextAlign.Center,
text = "Comment on workout...",
style = TextStyle(
fontSize = 14.sp,
color = colorResource(id = R.color.mono4),
fontFamily = FontFamily(Font(R.font.josefin_san_regular))
)
)
},
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
value = commentText,
onValueChange = { commentText = it }
)
This is internal behaviour, you will need to alter the source coe to fix it, or implement your own composable, something like:-
#OptIn(ExperimentalAnimationApi::class)
#Composable
fun TinyTextCapture(){
var value by remember { mutableStateOf("") }
Box(contentAlignment = Alignment.Center){
TextField(
modifier = Modifier.height(32.dp),
value = value, onValueChange = { value = it }
)
AnimatedVisibility(visible = value.isEmpty()) {
Text("Label")
}
}
}
The default label parameter has a default padding from top start, that is why it was seen as being pushed downwards. If I were you, I would not go about editing the source of something as basic as a TextField since it has so many internal dependencies that it is all a mess.
You could also do without the AnimatedVisibility, and also apply a ConstraintLayout to get it at the start of the TextField in contrast to its absolute centered position right now.

Categories

Resources