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
})
}
Related
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,
)
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:
This question already has an answer here:
Compose Layout: Align relative to centered item (eg. toRightOf)
(1 answer)
Closed 1 year ago.
I have the following layout
This has the text aligned to the center and the image is aligned to the end of the parent. I'm in the process of learning Jetpack compose and was wondering if it is possible for the children of the row to specify their alignment (gravity)?
I can achieve the above layout using a constraint layout.
Here is my current solution:
ConstraintLayout(
modifier = Modifier.fillMaxWidth()
) {
val (logo, avatar) = createRefs()
Text(
text = "Some Text",
modifier = Modifier.constrainAs(logo) {
centerHorizontallyTo(parent)
centerVerticallyTo(parent)
}
)
Image(
imageVector = Icons.Rounded.Person,
contentDescription = stringResource(id = R.string.profile_pic),
modifier = Modifier
.size(60.dp)
.clip(CircleShape)
.background(Color.LightGray)
.padding(4.dp)
.constrainAs(avatar) {
start.linkTo(logo.end)
linkTo(logo.end, parent.end, bias = 1f)
}
)
}
Can this also be achieved using a Row/Column setup?
Look so simple.
Column+Row:
Column(Modifier.fillMaxWidth()) {
Row(
Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
){
Box(Modifier.weight(1f))
Text(
"Simple text",
textAlign = TextAlign.Center,
modifier = Modifier.weight(1f)
)
Icon(
painter = painterResource(id = R.drawable.ic_launcher_background),
contentDescription = "Icon",
Modifier.weight(1f)
)
}
}
Box:
Box(Modifier.fillMaxWidth()) {
Text(
"Simple text",
textAlign = TextAlign.Center,
modifier = Modifier.align(Alignment.Center)
)
Icon(
painter = painterResource(id = R.drawable.ic_launcher_background),
contentDescription = "Icon",
modifier = Modifier.align(Alignment.CenterEnd)
)
}
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.
I want to make a Row of -90 degrees rotated Text Composables to make something like below:
However this code (repro case):
#Preview(showBackground = true, backgroundColor = 0xffffffff)
#Composable
fun Preview_Row_With_Rotated_Text() {
Row {
Text(
text = "A text",
modifier = Modifier
.padding(2.dp)
.rotate(-90f),
maxLines = 1,
)
Text(
text = "A text which is a bit longer",
modifier = Modifier
.padding(2.dp)
.rotate(-90f),
maxLines = 1,
)
Text(
text = "A text which is kinda longer than previous one",
modifier = Modifier
.padding(2.dp)
.rotate(-90f),
maxLines = 1,
)
}
}
produces this:
The Row uses old width of Text composables (the width of non-rotated Text) to place them one after another.
Where is the reason of this problem?
You can try using it in a Column and then rotating that Column by -90f:
#Composable
fun Main() {
Column(
modifier = Modifier
.width(200.dp)
.rotate(-90f)
) {
MyText(text = "Financial Advice")
MyText(text = "Strategy and Marketing")
MyText(text = "Information Technology")
}
}
#Composable
fun MyText(text: String) {
Text(
text = text,
modifier = Modifier
.padding(4.dp)
.fillMaxWidth()
.background(MaterialTheme.colors.secondary)
.padding(16.dp),
textAlign = TextAlign.Center,
maxLines = 1
)
}