I am using two Spacer to give space between view and give padding to bottom item. Now I want to combine both Spacer, but unable to understand how can I give in order. Can anyone guide me how can I achieve that.
Column(
modifier = Modifier
.fillMaxHeight()
.verticalScroll(rememberScrollState())
.padding(20.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Text()
Spacer(modifier = Modifier.weight(1f))
Spacer(modifier = Modifier.height(20.dp))
Button()
}
Visual effect
Thanks
If you want to give a vertical padding to the Button just apply Modifier.padding(top=20.dp) in the Button removing the 2nd Spacer.
No reason to use a Spacer with height(20.dp) when the 1st Spacer just covers all the space between the Text and the Button.
Column(
modifier = Modifier
.fillMaxHeight()
.verticalScroll(rememberScrollState())
.padding(20.dp),
verticalArrangement = Arrangement.SpaceBetween
) {
Text("text")
Spacer(modifier = Modifier.weight(1f))
//Spacer(modifier = Modifier.height(20.dp))
Button(onClick = {}, modifier=Modifier.padding(top=20.dp)){
Text("Button")
}
}
Related
I have 3 Columns in a parent Column:
Box(
modifier = Modifier
.fillMaxSize()
) {
Column(
verticalArrangement = Arrangement.Top,
modifier = Modifier.fillMaxSize()
) {
MenuHeader()
Column(
verticalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxHeight().background(color = Color.Blue)
) {
Text("Middle Section with remaining height")
}
MenuTabBar()
}
}
And I want the middle column to be the full middle height, between the MenuHeader() and the MenuTabBar().
I've tried to set the Arrangement to .Top, and .SpaceBetween, but neither work?
When I do .Top, the bottom bar disappears, I'm assuming the middle column is pushing it out of view because of the .fillMaxHeight.
Both MenuHeader and MenuTabBar have the following modifier:
Column(
modifier = Modifier
.fillMaxWidth()
) {
Am I supposed to modify the children in this case, or the parent column?
I just had to add .weight(1f) to middle Column modifier
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,
)
I am currently trying to implement a gridview, it consists of 2 columns. I know i can implement my own grid view using columns and rows, but i just want to use existing approach although it is experimental.
#Composable
fun MyGridScreen() {
LazyVerticalGrid(cells = GridCells.Fixed(2), modifier = Modifier.fillMaxSize(),contentPadding = PaddingValues(12.dp)) {
items(15) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(10.dp)
.height(80.dp)
.background(Color.Red)
.aspectRatio(1f)
) {
Text("Grid item $it", color = Color.White)
}
}
}
}
Below is the result i achieved. I can't put space below the item :(
You need to set verticalArrangement and horizontalArrangement properties on the LazyVerticalGrid composable.
This will space the items by 10.dp in both the vertical and horizontal axis.
#Composable
fun MyGridScreen() {
LazyVerticalGrid(
cells = GridCells.Fixed(2),
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(12.dp),
verticalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp
) {
items(15) {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier
.padding(10.dp)
.height(80.dp)
.background(Color.Red)
.aspectRatio(1f)
) {
Text("Grid item $it", color = Color.White)
}
}
}
}
Padding is exactly what you need in this case. But you need to understand that in compose modifiers order means a lot. By moving background modifier in between padding and sizes modifiers, you'll get what you need. And clickable ripple will work the same.
Check out more how modifiers order works: https://stackoverflow.com/a/65698101/3585796
.padding(10.dp)
.background(Color.Red)
.height(80.dp)
.aspectRatio(1f)
p.s. if you need your items to be a square, just put your box in one more box. Looks like width of items in LazyVerticalGrid gets overridden by the grid to fill max width, not sure if that's a bug or a feature.
Is there something like ScrollView fillViewPort in Jetpack Compose Column?
See this example:
#Composable
fun FillViewPortIssue() {
Column(
Modifier
.fillMaxSize()
.padding(16.dp)
) {
for (i in 0..5) {
Box(
modifier = Modifier
.padding(vertical = 8.dp)
.background(Color.Red)
.fillMaxWidth()
.height(72.dp)
)
}
Spacer(modifier = Modifier.weight(1f))
Button(
modifier = Modifier.fillMaxWidth(),
onClick = { /*TODO*/ }
) {
Text("Ok")
}
}
}
This is the result:
When the device is in landscape, the content is cropped, because there's no scroll.
If I add the verticalScroll modifier do the Column...
...
Column(
Modifier
.verticalScroll(rememberScrollState()) // <<-- this
.fillMaxSize()
.padding(16.dp)
) {
...
... the scroll problem is fixed, but the button goes up, like this.
In the traditional toolkit, we can fix this using ScrollView + fillViewPort property. Is there something equivalent to Compose?
Just change the order of the modifiers worked...
Thanks to Abhishek Dewan (from Kotlin Slack channel)!
Column(
Modifier
.fillMaxSize() // first, set the max size
.verticalScroll(rememberScrollState()) // then set the scroll
) {
I had a similar issue recently and substituted verticalScroll for scrollable(rememberScrollState(), Orientation.Vertical) which seemed to work for my case and allow the screen to fill its viewport while allowing scrolling
How to create vertical dividers with Jetpack Compose? I try to use Spacer and Box to do it, but it doesn't show up at all. Here is what i tried:
Box(
modifier = Modifier
.fillMaxHeight()
.width(2.dp)
.background(color = Color.Black)
)
But that doesn't work at all. So how to do vertical divider in Jetpack Compose?
You can use the Divider composable with the width(xx.dp) modifier applying an intrinsic measurements to its parent container.
Something like:
Row(Modifier
.height(IntrinsicSize.Min) //intrinsic measurements
.fillMaxWidth()
.background(Color.Yellow)) {
Text("First Text")
Divider(
color = Color.Red,
modifier = Modifier
.fillMaxHeight() //fill the max height
.width(1.dp)
)
Text("Second text")
}
As explained in the doc:
The Row composable's minIntrinsicHeight will be the maximum minIntrinsicHeight of its children. The Divider element's minIntrinsicHeight is 0 as it doesn't occupy space if no constraints are given; the TextField minIntrinsicHeight will be that of the content given a specific width. Therefore, the Row element's height constraint will be the max minIntrinsicHeight of the TextFields content. The Divider will then expand its height to the height constraint given by the Row.
Here is a VerticalDivider Composable, which you can use the same way as the built-in Divider horizontal one.
#Composable
fun VerticalDivider(
modifier: Modifier = Modifier,
color: Color = MaterialTheme.colors.onSurface.copy(alpha = DividerAlpha),
thickness: Dp = 1.dp
) {
Box(
modifier
.fillMaxHeight()
.width(thickness)
.background(color = color)
)
}
private const val DividerAlpha = 0.12f
You can use BOX ,SPACER or DIVIDER to create a vertical divider
Row(modifier = Modifier.height(20.dp)) {
Text("TEXT 1")
Box(
modifier = Modifier
.fillMaxHeight()
.width(2.dp)
.background(Color.Red)
)
Spacer(
modifier = Modifier
.fillMaxHeight()
.width(2.dp)
.background(Color.Black)
)
Divider(color = Color.Blue, modifier = Modifier
.fillMaxHeight()
.width(2.dp))
Text("TEXT 2")
}
Code result: