How to Fill Height with middle Column in Kotlin Compose - android

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

Related

How to order modifier in spacer in jetpack compose

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")
}
}

How to split screen in Jetpack compose

I want to split my screen like this, first on half(0.5f of whole screen), then this half on other half(0.25f of whole screen), and then again to split it on half(0.125f), but when do it, it overlaps one of the screens and is not splited as expected
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomCenter) {
MapLoad()
//0.5f of screen
Column(
modifier = Modifier
.fillMaxHeight(0.5f)
.fillMaxWidth()
.background(color = Purple200)
) {
//0.25f
Column(
modifier = Modifier
.fillMaxHeight(0.5f)
.fillMaxWidth()
.background(color = NotFoundLabel)
) {
//0.125f
Column(
modifier = Modifier
.fillMaxHeight(0.5f)
.fillMaxWidth()
.background(color = LightBlue)
) {
Text("SOME TEXT ONE",Modifier.fillMaxSize().background(color = Color.Red))
}
//0.125f
Column(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight(0.5f)
.background(color = Color.Cyan)
) {
Text("SOME TEXT TWO",Modifier.fillMaxSize().background(color = Color.White))
}
}
}
}
The strange thing is when I change last column with cyan color .fillMaxHeight(0.5f) to 1f it fill the whole half of the space.
Any ideas?
Modifier.fillMaxHeight takes part of the size available at the time of view measuring.
When you're using two of these, at first view takes the half size available, and the second one takes half of what's left.
You can use Modifier.fillMaxHeight(1f) for the second view, but using Modifier.weight(1f) for both seems clearer.

how to add space between grid items in jetpack compose

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.

Jetpack Compose horizontal alignment issue

I need the image and text view to be positioned to the start of the card, with the columns children aligned center horizontally, however as you can see from the photo the column is somehow being stretched the width of the screen which is putting the image and text views in the center. Can anyone see any issues with my code on this?
#Composable
fun TrainerCard(profile: TrainerProfile) {
Card(modifier = Modifier
.height(180.dp)
.fillMaxWidth()
.padding(4.dp)) {
Column(modifier = Modifier
.fillMaxHeight()
.width(120.dp)
.border(1.dp, color = Color.Red),
horizontalAlignment = Alignment.CenterHorizontally) {
Image(
modifier = Modifier
.size(120.dp)
.padding(top = 4.dp, start = 4.dp),
painter = painterResource(R.drawable.pokepals_logo),
contentDescription = null
)
Text(
text = profile.trainerName,
style = MaterialTheme.typography.subtitle1)
}
}
}
In your Column add the wrapContentWidth(Alignment.Start) modifier:
Column(modifier = Modifier
.fillMaxHeight()
.width(120.dp)
.wrapContentWidth(Alignment.Start)
.border(1.dp, color = Color.Red),
horizontalAlignment = Alignment.CenterHorizontally
)

Provide different alignments to composables within 'Column'

I have a 'Text' and another composable within a Column. I want to put the Text to the top and the layout defined by the composable to the bottom. I am not able to find a way to provide different alignments to the 'elements' within Column, as the alignment/arrangement specified in the 'Modifier' of Column works for all the 'elements' within it. My current code aligns both to the bottom. This is my code:
#Composable
fun SignUpDetails(navController: NavController) {
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "First Screen\n" +
"Click me to go to Second Screen",
color = Color.Green,
style = TextStyle(textAlign = TextAlign.Center),
modifier = Modifier
.padding(24.dp)
.clickable(onClick = {
// this will navigate to second screen
navController.navigate("second_screen")
})
)
ProgressBar1UI()
}
}
How do I achieve my requirement?
You can use the verticalArrangement = Arrangement.SpaceBetween:
Place children such that they are spaced evenly across the main axis, without free space before the first child or after the last child
Something like:
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.SpaceBetween
) {
Text( /*...*/ )
ProgressBar1UI()
}
Otherwise you can use something different like a Box and the Modifier.align:
Box(modifier = Modifier.fillMaxSize()) {
Text(
modifier = Modifier
.align(Alignment.TopCenter)
)
ProgressBar1UI(Modifier.align(Alignment.BottomCenter))
}
The other way you can achieve such behavior (one view top second view bottom) is to add the Spacer component with a weight modifier between items.
#Composable
fun Example() {
Column {
Text("FirstText")
Spacer(modifier = Modifier.weight(1f))
Text("SecondText")
}
}

Categories

Resources