添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

Is it possible to do weights in Jetpack Compose? For example, I'd like to set it up in such a way that one item is weighted as 1/3 of a layout, and the other takes up the remaining 2/3.

In the XML/ViewGroup style, you can achieve this using LinearLayouts and ConstraintLayouts. To my dismay, however, it doesn't seem possible using Jetpack Compose.

Example :

In ConstraintLayout, this is done as follows:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:id="@+id/red"
        android:background="@color/red"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/blue"
        app:layout_constraintHorizontal_weight="1"/>
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:id="@+id/blue"
        android:background="@color/blue"
        app:layout_constraintStart_toEndOf="@id/red"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_weight="2"/>
</androidx.constraintlayout.widget.ConstraintLayout>

In LinearLayouts, this is done as follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:id="@+id/red"
        android:background="@color/red"
        android:layout_weight="1"/>
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:id="@+id/blue"
        android:background="@color/blue"
        android:layout_weight="2"/>
</LinearLayout>

I know that you can use Tables to get evenly distributed things, but I want an uneven distribution.

After you ask a question here, if you get an acceptable answer, you should “accept” the answer by clicking the check mark next to it. This scores points for you and for the person who answered your question. You can find out more about accepting answers here: How do I accept an answer?, Why should we accept answers?, What should I do if someone answers my question?. – MarianD Sep 3, 2022 at 18:48 for those fanatics like me, that really want to avoid nested layouts, compose is not affected by this! – ZooMagic Sep 8, 2022 at 9:58

to divide the vertical/horizontal space remaining after measuring unweighted child elements and distribute it according to this weight

 Column {
        Row(modifier = Modifier.weight(2.0f, true)) {
            Box (
                modifier = Modifier.fillMaxWidth().fillMaxHeight(),
                backgroundColor = Color.Red
        Row(modifier = Modifier.weight(1.0f, true)) {
            Box (
                modifier = Modifier.fillMaxWidth().fillMaxHeight(),
                backgroundColor = Color.Blue,
                gravity = ContentGravity.Center
                Text(text = "A sample text")
        Row(modifier = Modifier.weight(2.0f, true)) {
            Box (
                modifier = Modifier.fillMaxWidth().fillMaxHeight(),
                backgroundColor = Color.Yellow
                How do I know how much high should be weight of my views? Let's say I have a column with three objects. The second one takes the most part of layout so that the first and the last objects have the default height and the second one should fill the place between the first and last one. In XML you could put those objects in LinearLayout and set the weight of the second view to 1. How do I achieve that in in Jetpack compose? Thanks
– Mark Delphi
                Aug 18, 2022 at 22:59

The "0.1.0-dev04" release of Jetpack Compose contains changes, and FlexRow is deprecated. I can propose the following solution:

Row {
    Card(modifier = LayoutFlexible(1f), color = Color.Red) {
        Container(expanded = true, height = 50.dp) {
    Card(modifier = LayoutFlexible(2f), color = Color.Green) {
        Container(expanded = true, height = 50.dp) {

Result:

The LayoutFlexible(flex = _f) helps us to solve the issue and Modifier can be applied to any container.

sectionHeight: Dp = 80.dp val weight = remember { weightHeightMeasurement(pokemonWeight) } val height = remember { weightHeightMeasurement(pokemonHeight) } modifier = Modifier.fillMaxWidth() PokemonDetailDataItem( dataValue = weight, dataTag = stringResource(id = R.string.str_weight), dataUnit = stringResource(id = R.string.str_kg), dataIcon = painterResource(id = R.drawable.ic_pokemon_weight), modifier = Modifier.weight(1f) Spacer(modifier = Modifier .size(1.dp, sectionHeight) .background(Color.LightGray)) PokemonDetailDataItem( dataValue = height, dataTag = stringResource(id = R.string.str_height), dataUnit = stringResource(id = R.string.str_meter), dataIcon = painterResource(id = R.drawable.ic_pokemon_height), modifier = Modifier.weight(1f) @Composable fun PokemonDetailDataItem( dataValue: String, dataTag: String, dataUnit: String, dataIcon: Painter, modifier: Modifier = Modifier val iconSize : Dp = 50.dp val attributeSpacing : Dp = 8.dp val attributeValueSize = 18.sp val attributeTagSize = 12.sp val displayText = "$dataValue $dataUnit" verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, modifier = modifier Icon( painter = dataIcon, contentDescription = null, modifier = Modifier.size(iconSize), tint = MaterialTheme.colors.onSurface Spacer(modifier = Modifier.width(10.dp)) Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center Text( text = displayText, fontFamily = Nunito, fontWeight = FontWeight.Bold, fontSize = attributeValueSize, color = MaterialTheme.colors.onSurface Text( text = dataTag, fontFamily = Nunito, fontWeight = FontWeight.Normal, fontSize = attributeTagSize, color = Color.LightGray

Output

Similarly, use Row to place items horizontally on the screen. Both Column and Row support configuring the alignment of the elements they contain.

  @Composable
    fun ArtistCard(artist: Artist) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            Image(/*...*/)
            Column {
                Text(artist.name)
                Text(artist.lastSeenOnline)

Use Box to put elements on top of another. Box also supports configuring specific alignment of the elements it contains.

@Composable
fun ArtistAvatar(artist: Artist) {
    Box {
        Image(/*...*/)
        Icon(/*...*/)
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.