Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed
Asked Answered
C

4

29

I am using ComposeView inside my recyclerview item layout to work with jetpack compose. I am getting weird issue when I open screen

Error

java.lang.IllegalStateException: Vertically scrollable component was measured with an infinity maximum height constraints, which is disallowed. One of the common reasons is nesting layouts like LazyColumn and Column(Modifier.verticalScroll()). If you want to add a header before the list of items please add a header as a separate item() before the main items() inside the LazyColumn scope. There are could be other reasons for this to happen: your ComposeView was added into a LinearLayout with some weight, you applied Modifier.wrapContentSize(unbounded = true) or wrote a custom layout. Please try to remove the source of infinite constraints in the hierarchy above the scrolling container.

I tried to follow this stack overflow but it didn't work

main_activity.xml

      <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="parent" />

item_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/itemComposable"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

</androidx.constraintlayout.widget.ConstraintLayout>

  

viewholder.kt

class OptionsViewHolder(val binding: ItemLayoutBinding) : Recyclerview.ViewHolder(binding.root) {

    private val context = binding.root.context

    companion object {
        fun from(parent: ViewGroup): OptionsViewHolder {
            return OptionsViewHolder(
                ItemLayoutBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
            )
        }
    }

    fun bindChoice() {
        binding.itemComposable.setContent {
            BoxWithConstraints {
                LazyColumn(
                    modifier = Modifier
                        .fillMaxWidth()
                        .height([email protected])
                        .verticalScroll(rememberScrollState())
                ) {
                    items(getOptions()) { option ->
                        Text(text = option)
                    }
                }
            }
        }
    }

    private fun getOptions() = mutableListOf(
        context.getString(R.string.monitor),
        context.getString(R.string.pressure),
        context.getString(R.string.not_sure)
    )
}
Clydeclydebank answered 29/7, 2022 at 10:39 Comment(0)
N
12

You are using a LazyColumn in a RecyclerView which is not allowed. A LazyColumn is the equivalent of a RecyclerView in Compose. So you are nesting RecyclerViews or LazyColumns.

Nielsen answered 29/7, 2022 at 10:47 Comment(8)
so what should I do ?Clydeclydebank
Replace LazyColumn with Column.Nielsen
then how can I make items which is nested ?Clydeclydebank
Column doesn't have item property?Clydeclydebank
so how can getOptions() pass a list ?Clydeclydebank
I think issue here is BoxWithConstraints returning Constraints.Infinity as maxHeight. Check height you get from BoxWithConstraints. Using LazyColumn with fixed height is allowed but not with infinite constraints. And i agree about the RecyclerView and LazyColumn being together is redundantLiquescent
@Liquescent my old has multiple view holder and I want to use jetpack compose in new viewholder that's why I am using that.Clydeclydebank
Putting Composables inside a RecyclerView as items might hinder your performance. In this video it's not advised. youtu.be/Ry-3xlElUe4?t=806Liquescent
B
5

In compose if you are using Lazy column, you should mention the height of lazy column.

    LazyColumn(
            modifier = Modifier
                .height(100.dp)
        ){
// your code goes here
}
Bricker answered 20/3 at 14:40 Comment(0)
O
2

Making a nested vertical List in Jetpack Compose.

Hey, its quite easy, I figured it out.. say we have a data structure (in kotlin)

val allTransactions = List<Transaction>

val monthlyTransaction = Transaction(monthName: String, monthlyTransactions: List< MonthlyTransactions>)

val monthlyTransaction = MonthlyTransaction(amount: String, date: String)

first have a LazyColumn

@Composable
fun mainFunction (){
    LazyColumn {
        if (allTransactions.isNotEmpty()) {
            items(allTransactions.size) { index ->
                // pass each model 
                TransactionComposable(model = allTransactions[index])
            }
        }
    }
}

@Composable
fun TransactionComposable(transaction: Transaction) {
    
    // make the title outside the column so it will be on top of the list
    Text(text = transaction.monthName)  

    Column {
        // make a for each loop inside the column
        transaction.monthlyTransactions.forEach { monthlyTransaction ->
                // for each of your iteration, call your inner list item inside a a row
                Row {
                    TransactionDetailComponent (monthlyTransaction)
                }
            }
        }
    }
}
Ortegal answered 21/2, 2023 at 20:57 Comment(0)
M
0

In my case I don't have RecyclerView, just Column (ScrollView):

Column(
    modifier = Modifier
        .navigationBarsPadding()
        .imePadding()
        .verticalScroll(rememberScrollState()), // This line throws error
    horizontalAlignment = Alignment.CenterHorizontally,
)

In most cases it works right.

Marie answered 29/11, 2023 at 9:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.