In Jetpack Compose, when using Text, we can center text using TextAlign:
Text(
text = "How many cars are in the garage",
textAlign = TextAlign.Center
)
But if we're looking to get the position of a click within a Text composable, we use ClickableText:
ClickableText(
text = AnnotatedString("Click Me"),
onClick = { offset ->
Log.d("ClickableText", "$offset -th character is clicked.")
}
)
However I don't see how to center text in ClickableText? I can use gravity, but that will only center the component, not the text inside of it.
You can define the textAlign in the style parameter:
ClickableText(
text = AnnotatedString("Click Me"),
style = TextStyle(
textAlign = TextAlign.Center),
onClick = { offset ->
}
)
Related
Lest simplify my situation to the current:
Row(
modifier = Modifier
.background(Color.Red),
) {
Text(
text = ELLIPSIZE_THIS_TEXT,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = LEAVE_THIS_TEXT_NOT_ELLIPSIZED,
maxLines = 1,
overflow = TextOverflow.Visible,
)
}
If I add weight(1f) to the first text modifier, it works as expected, but the Row took all the line. But my goal is to take only required place and if I have not enough place - ellipsize the first text.
And I need behavior from images 2 and 3.
You can use fill property for this . Setting it to false will result in wrapping the text if small and ellipsis text in case its bigger. Try this out .
Row(
modifier = modifier
.background(Color.Red).padding(10.dp),
) {
Text(
text = "Jetpack Compose Ui Tool-kit",
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier=Modifier.weight(1f, fill = false)
)
Spacer(modifier = Modifier.width(12.dp))
Text(
text = "LEAVE_THIS_TEXT",
maxLines = 1,
overflow = TextOverflow.Visible,
)
}
I have 3 texts in one row and then another three in another row inside a LazyColumn
I want to align the "text" in the center of the first row with "15.025" value in the second row
I've used
TextAlign.Center
on both of the Texts and
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
set this on the Row but it doesn't work. Any tips please?
I'm pretty new in Compose, sorry for the basic question.
You can use Modifier.weight to make the width of "left view" equals to the width of "right view". It will make the middle text on each row always center.
Row(Modifier.fillMaxWidth()) {
Text(
text = "Start",
modifier = Modifier.weight(1f)
)
Text(
text = "Center",
textAlign = TextAlign.Center, // you can also fixed the width of center text
)
Text(
text = "End",
modifier = Modifier.weight(1f),
textAlign = TextAlign.End
)
}
If your text content is always short, you can also use Box to make the middle text always center.
Box(Modifier.fillMaxWidth()) {
Text(text = "Start", modifier = Modifier.align(Alignment.CenterStart))
Text(text = "Center", modifier = Modifier.align(Alignment.Center))
Text(text = "End", modifier = Modifier.align(Alignment.CenterEnd))
}
This is what I wanted to achieve and with the help of #Linh I did
Here's how I did it.
Column(Modifier.fillMaxSize()) {
Row(Modifier.fillMaxWidth()) {
Text(
text = "Start",
modifier = Modifier.weight(1.5f),
textAlign = TextAlign.Start
)
Text(
text = "Center",
modifier = Modifier.weight(1f),
textAlign = TextAlign.Start
)
Text(
text = "End",
modifier = Modifier.weight(1f),
textAlign = TextAlign.End
)
}
}
Thanks again for the help.
TextField(
value = newCommentState.value,
textStyle = TextStyle(
fontSize = 16.sp,
color = MaterialTheme.colors.primary
),
onValueChange = { newCommentState.value = it },
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.White
),
keyboardOptions = KeyboardOptions(capitalization = KeyboardCapitalization.Sentences),
placeholder = {
Text(
"Add your comment",
color = colorResource(R.color.disabled_gray)
)
}
)
Spacer(modifier = Modifier.width(8.dp))
ClickableText(
modifier = Modifier.defaultMinSize(70.dp),
text = AnnotatedString("Post"),
style = TextStyle(
color = if (newCommentState.value.text.isNullOrEmpty())
colorResource(
R.color.disabled_gray
) else colorResource(R.color.green),
fontSize = 20.sp,
),
onClick = {
if (newCommentState.value.text.isNullOrEmpty())
Toast.makeText(
context,
"Cant post empty comment!",
Toast.LENGTH_SHORT
).show()
else
coroutineScope.launch { createComment(context) }
},
)
I have written this code for a textfield that takes in user comments and has a Clickable Text "Post" next to it. The text "Post" gets pushed and wrap when the textfield has text outside the width.
I want the text to get wrapped without hitting the "Post" .
You can solve this by adding Modifier.weight(1f) to your TextField. From documentation:
The parent will divide the horizontal space remaining after measuring unweighted child elements and distribute it according to this weight.
You may either give your views the proper weight like this answer as an example or you can only give the TextField only weight, and the other views to be without weight which as per documentation will do the below quote .
The parent will divide the horizontal space remaining after measuring unweighted child elements and distribute it according to this weight
I am trying to change the style of a clickable text, mostly the font and color of it.
I am using for now:
text = AnnotatedString(stringResource(R.string.forgot_password)),
onClick = { offset ->
Log.d("ClickableText", "$offset -th character is clicked.")
} ```
This just using the default theme.
How can I apply a different color or font or fontsize ?
Thanks
It offers the style parameter. You could just do something like
ClickableText(
text = AnnotatedString(""),
onClick = {},
style = TextStyle(
color = Blue,
fontSize = 26.sp,
fontFamily = FontFamily.Cursive
)
)
If you are using Android Studio, you can just press Ctrl + P on Windows and Cmd + P on Mac to check the available parameters. The optional parameters are not inserted by code completion since they can be many.
To use fonts, define a fontFamily property, like this
private val Montserrat = FontFamily(
Font(R.font.montserrat_regular, FontWeight.Normal),
Font(R.font.montserrat_medium, FontWeight.Medium),
Font(R.font.montserrat_bold, FontWeight.Bold),
)
then add it to your Typography
val Typography = Typography(
h1 = TextStyle(
fontFamily = Montserrat,
fontSize = 96.sp,
fontWeight = FontWeight.Normal,
lineHeight = 117.sp,
letterSpacing = (-1.5).sp
),
which is added to your theme
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
If you then use these styles in your text it will pick the family you specified, or you can override, like this
Text(
text = "Sample text",
style = MaterialTheme.typography.body1.copy(
color = Color.Blue,
fontFamily = Montserrat,
),
)
You can use style keyword to add font, for example:
ClickableText(
text = AnnotatedString(text = "Clickable Text Font Example"),
style = TextStyle(
fontFamily = FontFamily(Font(R.font.your_font)),
),
onClick = {}
)
Is it possilble as of 1.0.0-alpha03 to align text center vertically without nesting components Stack -> Text
Text(
modifier = Modifier
.size(150.dp, 30.dp)
.background(Colors.ChipGray, RoundedCornerShape(50)),
textAlign = TextAlign.Center,
text = start.value.format(DateTimeFormatter.ofPattern("dd. MM. HH:mm")),
)
In General, it is possible but I would not suggest it.
You could use offset to shift the text relative to the background by half of the font size, but I am not sure if you can access the height of the used font here.
Text(
text = start.value.format(DateTimeFormatter.ofPattern("dd. MM. HH:mm")),
textAlign = TextAlign.Center,
modifier = Modifier
.size(150.dp, 30.dp)
.background(Color.Gray, RoundedCornerShape(50))
.offset(y = fontHeightHalf)
)
Use the stack instead, like:
Stack (
alignment = Alignment.Center,
modifier = Modifier
.size(150.dp, 30.dp)
.background(Color.Gray, RoundedCornerShape(50)),
) {
Text(
text = start.value.format(DateTimeFormatter.ofPattern("dd. MM. HH:mm")),
textAlign = TextAlign.Center
)
}
Edit: Updated version to 1.0.0-alpha03