Home > Enterprise >  What is the equivalent of Expanded widget of Flutter in Jetpack Compose?
What is the equivalent of Expanded widget of Flutter in Jetpack Compose?

Time:09-09

I am pretty much new to Jetpack Compose and I want to create a simple business card app like this:

enter image description here

The way I want to achieve this layout is to create two main Columns, one for the upper part (logo with name and title) and one for the lower part of the screen (contact details). I want the first Column to take all the remaining space of the screen, so the lower Column goes to the end of the page. In Flutter I would place both of the Columns in a parent Column and wrap the first Column with Expanded, and it would do the job. So how to achieve the same behavior in Jetpack Compose? The code is as follows:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BusinessCardTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    BusinessCard()
                }
            }
        }
    }
}

@Composable
fun LogoNameTitle() {
    Column(
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Image(
            painter = painterResource(id = R.drawable.android_logo),
            contentDescription = "",
        )
        Text("Jennifer Doe", color = Color.White)
        Text("Android Developer Extraordinaire", color = Color.Green)
    }
}

@Composable
fun ContactInformation() {
    Column() {
        Row() {
            Icon(imageVector = Icons.Rounded.Phone, contentDescription = "", tint = Color.Green)
            Text(" 11 (123) 444 555 666", color = Color.White)
        }
        Row() {
            Icon(imageVector = Icons.Rounded.Share, contentDescription = "", tint = Color.Green)
            Text("@AndroidDev", color = Color.White)
        }
        Row() {
            Icon(imageVector = Icons.Rounded.Email, contentDescription = "", tint = Color.Green)
            Text("[email protected]", color = Color.White)
        }
    }
}

@Composable
fun BusinessCard() {
    Surface(color = Color.DarkGray) {
        Column(
            modifier = Modifier.padding(16.dp)
        ) {
            LogoNameTitle()
            ContactInformation()
        }
    }
}

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun BusinessCardPreview() {
    BusinessCardTheme {
        BusinessCard()
    }
}

And the current output is:

enter image description here

CodePudding user response:

Use as parent container a Column and just apply the weight(1f) modifier to the 1st nested Column (name and title).

Something like:

Column(modifier = Modifier.fillMaxSize()){
   
   Column(Modifier.fillMaxWidth().weight(1f)){
        //Logo and title    
   }
   Column(){
       //Contact info
        Text("First Name")
        Text("Surname")
        Text("Other info")
   }
}

enter image description here

Pls note that the weight modifier requires a ColumnScope. In your case use the modifier as parameter:

@Composable
fun LogoNameTitle(modifier: Modifier = Modifier) {
    Column(
        modifier = modifier,
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        //...
    }
}

@Composable
fun BusinessCard() {
    Surface(color = Color.DarkGray,modifier = Modifier.fillMaxSize()) {
        Column(
            modifier = Modifier.fillMaxSize().padding(16.dp)
        ) {
            LogoNameTitle(modifier=Modifier.weight(1f))
            ContactInformation()
        }
    }
}
  • Related