37

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

6 Answers 6

18

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.

Sign up to request clarification or add additional context in comments.

9 Comments

so what should I do ?
Replace LazyColumn with Column.
then how can I make items which is nested ?
Column doesn't have item property?
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 redundant
|
11

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
}

Comments

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

Comments

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.

Comments

0

Use this LazyListScope.


@Composable
fun NestedScrollingColumnsExample() {
    LazyColumn(
        modifier = Modifier
            .fillMaxSize(),
        contentPadding = PaddingValues(16.dp)
    ) {
        item {
            ListRow()
        }
        item {
            Spacer(modifier = Modifier.height(16.dp))
        }
        ListColumn(100)
    }
}


@Composable
fun ListRow() {
    LazyRow(
        modifier = Modifier
            .fillMaxWidth()
            .padding(horizontal = 16.dp)
    ) {
        items(10) { nestedIndex ->
            Text(
                text = "Row Item #$nestedIndex",
                fontSize = 14.sp,
                modifier = Modifier
                    .background(Color.Gray)
                    .padding(16.dp),
                color = Color.White
            )
        }
    }
}


fun LazyListScope.ListColumn(int: Int) {
    items(int) { outerIndex ->
        Text(
            text = "Outer Item #$outerIndex",
            fontSize = 18.sp,
            modifier = Modifier
                .background(Color.Blue)
                .padding(16.dp),
            color = Color.White
        )
    }
}

Comments

0

May be you try to use LazyColumn inside Column with .verticalScroll(rememberScrollState()) properties. In this case, remove the property.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.