androidandroid-studioandroid-jetpack-composemodifier

fraction in fillMaxHeight inside a column not work(android jetpack compose)


I have a column with two buttons. at first I used maxSize for my Column and i set the vertical arrangement of my buttons to the bottom as you see in this picture. but I wanted to raise the buttons between the center and bottom of screen(about 78% of the screen size from the top see this pic) so that it would be responsive in every screen. this is my approch :

 Column(
    modifier = Modifier
        .fillMaxWidth()
        .fillMaxHeight(0.78f),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Bottom

) {
    Button(
        modifier = Modifier.fillMaxWidth(0.7f),
        onClick = {}) {

        Text(text = "Sign Up")
    }

    Button(
        modifier = Modifier.fillMaxWidth(0.7f),
        colors = ButtonDefaults.buttonColors(containerColor = Color.White),
        onClick = {}) {

        Text(
            text = "Sign In",
            color = Brown
        )
    }
}

but the problem is that it remained the same and buttons are in the bottom as well. do you have any opinion to make what I want?


Solution

  • The explanation for the behavior you observed:

    If you use a Surface, the first child Composable will always have the same minimum size as the Surface. This was a decision intentionally made by the Android Development Team:

    Surface is not really a layout. [...] So we come up with propagateMinConstraints=true idea, now the content inside Surface has to fill the min size applied on Surface.

    There are two solutions:

    A) Set the Surface to the exact size that you need by removing the Modifier.fillMaxSize()

    B) Introduce an intermediate Composable, for example, a Column like this:

    Surface(
        modifier = Modifier.fillMaxSize()
    ) {
    
        Column(
            modifier = Modifier.fillMaxSize()
        ) {
    
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .fillMaxHeight(0.78f),  // should work now
                horizontalAlignment = Alignment.CenterHorizontally,
                verticalArrangement = Arrangement.Bottom
            ) {
                // ...
            }
        }
    }
    

    See also this stackoverflow question that goes more into depth.