Android Basic TextField alignment in Jetpack Compose - android

i am having problemas trying to align text in a BasicTextField inside a ROW in Jetpack Compose, the goal is to have the text in total center.
The code is the following:
Row(verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
BasicTextField(
modifier = Modifier
.height(40.dp)
.align(Alignment.CenterVertically),
value = "Hello",
onValueChange = {},
singleLine = true,
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
)
}
Here is a picture of the result:
Any ideas what's wrong?
Thanks!
Ariel

I found 2 ways to solve this problem:
The first is simpler if BasicTextField does not necessarily need to have a height of 40.dp, and the Row component can be responsible for setting a height:
Row(
modifier = Modifier.height(40.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
BasicTextField(
value = "Hello",
onValueChange = {},
singleLine = true,
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.Center),
)
}
The second way is in case your BasicTextField really needs to have a height of 40dp, and this responsibility cannot be assigned to the parent component (Row).
The strategy here is to wrap the BasicTextField with a box height of 40dp and then align it to the center of the parent:
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center
) {
Box(
modifier = Modifier.height(40.dp),
contentAlignment = Alignment.Center,
) {
BasicTextField(
value = "Hello",
onValueChange = {},
textStyle = TextStyle(textAlign = TextAlign.Center)
)
}
}
Note that in this second case it was necessary to change the assignment of the textStyle parameter of the BasicTextField:
Row(...) {
BasicTextField(
...
textStyle = TextStyle(textAlign = TextAlign.Center)
)
}
For both cases the visual result will be this:

Related

why this two items have different width in jetpack compose

Hey guys I am learning textfield in jetpack compose. I want to use multiple time so I make a function and use it. when I am passing start padding it decreases the width of other one. Can someone help me on this, where i am wrong here.
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
repeat(2){
val value = if (it == 1){
21.dp
}else {
15.dp
}
var textFieldValue by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue())
}
TextField(
value = textFieldValue,
singleLine = true,
onValueChange = {
if (it.text.length <= 4) {
textFieldValue = it
}
},
modifier = Modifier
.height(55.dp)
.width(88.dp)
.padding(start = value),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
colors = TextFieldDefaults.textFieldColors(
backgroundColor = OffWhite,
focusedIndicatorColor = TealLight,
cursorColor = TealLight
),
textStyle = RegularSlate20
)
}
}
It look like this
why my 2nd textfield is not 88.dp?
The order of the modifiers is important.
You have to use:
TextField(
//....
modifier = Modifier
.height(55.dp)
.padding(start = value) //apply the padding before the width modifier
.width(88.dp)
)

Jetpack Compose Textfield Alignment

I'm new to jetpack compose. I want to start typing from TextField's centervertically-start
position but I can't put "Example" to center
vertically-start position.
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.shadow(5.dp)
.background(Color.Yellow),
) {
BasicTextField(
value = text,
onValueChange = {onvalueChange(it)},
modifier = Modifier.weight(10f).background(Color.Blue).fillMaxSize(),
singleLine = true,
textStyle = LocalTextStyle.current.copy(
textAlign = TextAlign.Center
)
)
Image(painter = painterResource(id = R.drawable.ic_baseline_search_24),
contentDescription = "Search",
modifier = Modifier.weight(2f).fillMaxSize()
)
This is my code
And this is what I want to do.
Row has a verticalAlignment for this. Also, if you want your TextField left align like the picture, remove the textAlign (or change it but it default to start)
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.shadow(5.dp)
.background(Color.Yellow),
verticalAlignment = Alignment.CenterVertically,
) {
BasicTextField(
value = text,
onValueChange = {onvalueChange(it)},
modifier = Modifier.weight(10f).background(Color.Blue).fillMaxSize(),
singleLine = true,
)
Image(painter = painterResource(id = R.drawable.ic_baseline_search_24),
contentDescription = "Search",
modifier = Modifier.weight(2f).fillMaxSize()
)
}
Use background box to control, please try:
Row(
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
.shadow(5.dp)
.background(Color.Yellow),
) {
Box(Modifier.weight(10f).background(Color.Blue).fillMaxSize(),contentAlignment = CenterStart){
BasicTextField(
value = text,
onValueChange = { onvalueChange(it) },
modifier = Modifier.wrapContentHeight(
Alignment.CenterVertically),
singleLine = true,
textStyle = LocalTextStyle.current.copy(
textAlign = TextAlign.Start
)
)
}
Image(
Icons.Filled.Search,
contentDescription = "Search",
modifier = Modifier.weight(2f).fillMaxSize()
)
}

Android compose text overflow weight is not work

RI am developing an Android app using jetpack compose.
Here is a very basic UI component:
I want to add a button on the right side.
But if the name is very long, the button is gone.
My code is here:
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = rememberImagePainter(data = profileImg),
contentDescription = null,
modifier = Modifier
.size(56.dp)
.clip(CircleShape)
)
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier.weight(1F) // I set the weight in here but it doesn't work.
) {
Text(
text = "very very very very very very very long name",
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = "3 minutes ago",
)
}
}
Row {
Button()
Button()
}
}
How can I show the right button correctly?
You need to actually provide that weight to Row containing your Text & make sure you don't cover the entire width. e.g don't do just 1f.
You can do something like this; (This is done with compose_version = '1.0.1')
#Composable
fun Item() {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.weight(0.7f)
) {
Image(
painter = painterResource(R.drawable.ic_launcher_background),
contentDescription = null,
modifier = Modifier
.size(56.dp)
.clip(CircleShape)
)
Column(
verticalArrangement = Arrangement.Center,
) {
Text(
text = "very very very very very very very long name",
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = "3 minutes ago",
)
}
}
Button(
onClick = {}, modifier = Modifier
.wrapContentWidth()
.weight(0.3f)
) {
Text(text = "Button")
}
}
}
Output:
Here is a working code (I've removed useless Row, it's simpler that way)
#Composable
fun Test() {
Row(
modifier = Modifier.fillMaxWidth,
horizontalArrangement = Arrangement.spacedBy(5.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
painter = rememberImagePainter(data = profileImg),
contentDescription = null,
modifier = Modifier
.size(56.dp)
.clip(CircleShape)
)
Column(
verticalArrangement = Arrangement.Center,
modifier = Modifier.weight(1f) // I set the weight in here but it doesn't work.
) {
Text(
text = "very very very very very very very long name",
fontWeight = FontWeight.Bold,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
Text(
text = "3 minutes ago",
)
}
Button(onClick = { }) {
Text(text = "Btn1")
}
Button(onClick = { }) {
Text(text = "Btn2")
}
}
}
Even though the other question are right I am going to explain your mistake, to better understand what is going on.
So you need:
A Row() which will contain those 3:
Image
Column
and a Row with the two buttons
In other words something like:
Row() {
Image()
Column(weight:1f)
Row()
}
Your mistake is that you created a Row with two other Rows without weights and you get this weird output.
So if you simply delete your outer Row and move your Row of buttons like so it will work:

Jetpack Compose: No background in OutlinedTextField

I have two layers in my Compose layout: One for the actual content and the one above is a Box-wrapped OutlinedTextField for search queries.
Here's the sample code:
// Placeholder for layout content
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = stringResource(id = R.string.lorem_ipsum),
color = Color.Gray
)
}
// Overlaying Box with OutlinedTextField
Box(modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 64.dp)
) {
OutlinedTextField(
value = viewModel.query.value,
onValueChange = { viewModel.updateQuery(it) },
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.navigationBarsWithImePadding(),
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Characters,
autoCorrect = false,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.None
),
shape = CircleShape,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.White
),
placeholder = { Text(stringResource(id = R.string.search_input_placeholder)) },
maxLines = 1,
singleLine = true
)
}
Even though I'm setting
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.White
)
in the OutlinedTextField, the background stays transparent as you can see in the following screenshot:
Adding a background color on the OutlinedTextField's modifier is giving the whole row a rectangled background, which is also not the desired result.
The OutlinedTextField with it's CircleShape should only have a background inside of the shape. How can I achieve that?
I'm using Jetpack Compose version 1.0.4.
Reason
Unfortunately, in version 1.0.4, OutlinedTextField ignores the backgroundColor even if you specify it, so you can remove the colors parameter.
Support for it will be added in 1.1.0:
https://android-review.googlesource.com/c/platform/frameworks/support/+/1741240
It's already present in 1.1.0-alpha06 so you can play with it if you want. Your original code should produce desired outcome on that version.
Solution
To achieve what you want (before 1.1.0 is released) you can simply add a background modifier with the same shape:
.background(Color.White, CircleShape)
Since the order of modifiers is important, you should add it after you apply all the paddings (navigationBarsWithImePadding in your case). Like that:
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.navigationBarsWithImePadding()
.background(Color.White, CircleShape),
Note: Also be aware that you cannot use the label parameter with this approach, because the TextField with label will be higher than just the outline shape and these two shaped wouldn't match in size anymore.
Result
Entire code:
// Placeholder for layout content
Box(modifier = Modifier.fillMaxSize()) {
Text(
text = stringResource(id = R.string.lorem_ipsum),
color = Color.Gray
)
}
// Overlaying Box with OutlinedTextField
Box(modifier = Modifier
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp, top = 64.dp)
) {
OutlinedTextField(
value = viewModel.query.value,
onValueChange = { viewModel.updateQuery(it) },
modifier = Modifier
.fillMaxWidth()
.align(Alignment.BottomCenter)
.navigationBarsWithImePadding()
.background(Color.White, CircleShape),
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Characters,
autoCorrect = false,
keyboardType = KeyboardType.Text,
imeAction = ImeAction.None
),
shape = CircleShape,
placeholder = { Text(stringResource(id = R.string.search_input_placeholder)) },
maxLines = 1,
singleLine = true
)
}
How the final result looks like:

Jetpack Compose align Text content to center of the Scaffold

My Problem:
I want to place my Text() content to center of the page in Scaffold.
I tried "textAlign = TextAlign.Center" - It align the text in horizontal area alone. Not align the text in vertical area.
My code:
#Composable
fun ScaffoldWithTopBar() {
Scaffold(
topBar = {
TopAppBar(
title = {
Text(text = "Top App Bar")
},
navigationIcon = {
IconButton(onClick = {}) {
Icon(Icons.Filled.ArrowBack, "backIcon")
}
},
backgroundColor = MaterialTheme.colors.primary,
contentColor = Color.White,
elevation = 10.dp
)
}, content = {
Column(
modifier = Modifier
.fillMaxSize()
.background(Color(0xff8d6e63)),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
}
Text(
text = "Content of the page",
fontSize = 30.sp,
color = Color.White
)
})
}
Note: I haven't place this text into Column. I used directly.
My output:
Question:
How to place the text into the center of the parent?
Assign the fillMaxSize() to the parent container, not to the Text:
Box(Modifier.fillMaxSize(),
contentAlignment = Center
) {
Text(
text = "Content of the page",
fontSize = 30.sp,
modifier = Modifier
.background(Color(0xffb3e5fc)),
)
}
or:
Column(Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Content of the page",
fontSize = 30.sp,
modifier = Modifier
.background(Color(0xffb3e5fc)),
)
}
You need to place it inside a Box, and specify contentAlignment
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.fillMaxSize()
) {
Text(
text = "Content of the page",
fontSize = 30.sp,
modifier = Modifier
.background(Color(0xffb3e5fc)),
)
}
If you wanna align different Box children differently, you can use .align modifier for each item. Note that it's only available inside BoxScope, also there's same modifier for Column and Row.
Box(
modifier = Modifier
.fillMaxSize()
) {
Text(
text = "Content of the page", textAlign = TextAlign.Center,
fontSize = 30.sp,
modifier = Modifier
.background(Color(0xffb3e5fc))
.align(Alignment.Center)
)
}
Box(
modifier = Modifier
.fillMaxSize()
) {
Text(
text = stringResource(id = R.string.social_list_empty),
style = TextStyle(fontSize = 16.sp),
modifier = Modifier
.padding(8.dp)
.align(Alignment.Center),
textAlign = TextAlign.Center
)
}
Reference : For more sample codes of Jetpack Compose, check this
The content in Scaffold is a Composable function in which there is no position info for items by default. In your case, the default position of Text is the top left of its parent view. The solutions putting the Text inside the Box/Colum works, as now Text is put in the center of the Box or Colum, which takes the whole screen. We see Text is in the center of the screen, while the truth is Text is in the center of Box or Colum.

Categories

Resources