Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LazyColumn with items from viewModel crashes with IndexOutOfBounds when items size changes

I have a LazyColumn where I am displaying items from my DB, items are based on selected date when date changes items size changes and then app crashes with IndexOutOfBoundException here is the code

getting items form viewModel

val allMedicines by viewModel.getMedicineByTime(selectedDateMillis).collectAsStateWithLifecycle(initialValue = emptyList())

and lazy column code is as follows

if (allMedicines.isEmpty()) {
    AnimateLottieRaw(resId = R.raw.empty_box, modifier = Modifier.size(200.dp))
    Text(
        text = "No Medicines scheduled for today\ntry adding some using the + button below",
        modifier = Modifier.fillMaxSize(),
        fontFamily = dmSansFont,
        textAlign = TextAlign.Center,
    )
} else {
    LazyColumn(modifier = Modifier.fillMaxSize()) {
        items(allMedicines) { medicine ->
            MedicineCard(medicine = medicine) {
                onEvent(ClickEvents.EditMedicine(it))
            }
        }
    }
}

I am facing this error only when lazyColumn needs to recompose if I make selected date constant and give a particular date then there is no issue but when I make it so that user clickEvent changes selected date it will crash, so please give me any solution or any hint

I have used some log statements to check if the list is getting updated and yes it's size is getting updated, I have tried to change lazyColumn to work with item size rather than actual list the code for that is as follows


LazyColumn(modifier = Modifier.fillMaxSize()) {
     items(allMedicines.size) { pos ->
         val medicine = allMedicines[pos]
         MedicineCard(medicine = medicine) {
             onEvent(ClickEvents.EditMedicine(it))
         }
     }
}

but still not use

EDIT: I have replaced lazyColumn with a text and just displayed size of the items when date gets updated and it is working fine and displaying the items scheduled on that particualr date, so in my POV the issue here is not with the DB or the viewModel.

EDIT 2: for the time being I have removed the LazyColumn and replaced it with a normal column while iterating all Medicines manually, I know this isn't the way to do it but as a temporary measure, I had to do this, the code is as follows

Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())) {
            allMedicines.forEach {
                MedicineCard(medicine = it) {
                    onEvent(ClickEvents.EditMedicine(it))
                }
            }
        }

this is just a temporary solution and it is working fine as of now so the issue here is with lazyColumn I guess, please let me know of any solution or at least any sort of hint that might lead to a better solution

pastebin link for the error log

like image 321
trinadh thatakula Avatar asked Sep 13 '25 03:09

trinadh thatakula


2 Answers

My guess is that the list elements themselves and the size field of the list are not updated at the exact same time, so the list might already be shorter for a moment, but the size value still displays the old length, The LazyColumn then tries to display a position in your allMedicines list that actually does no longer exist, resulting in an IndexOutOfBoundsException.

I suggest that if you need the index of the position of the item in the LazyColumn, use itemsIndexed instead:

LazyColumn(modifier = Modifier.fillMaxSize()) {
     itemsIndexed(allMedicines) { index, medicine ->
         MedicineCard(medicine = medicine) {
             onEvent(ClickEvents.EditMedicine(index))
         }
     }
}

Note that the items function itself offers different parameters. The documentation mentions three variants:

  • items with providing a count
  • items with providing an Array
  • items with providing a List

Edit: As the answer below suggests, there is a bug in Jetpack Compose. It has been reported in the Google Issue Tracker, recently fixed and published with Compose Foundation Version 1.6.0-beta01. You can include it with the following dependency:

dependencies {
    implementation("androidx.compose.foundation:foundation:1.6.0-beta01")
}
like image 119
BenjyTec Avatar answered Sep 14 '25 18:09

BenjyTec


Please update new version 1.6.0-beta01 of compose foundation if you are using verion 1.6.0-alpha08 that exist issue about the children of SubcomposeLayout.

like image 45
Nang Le Duc Avatar answered Sep 14 '25 18:09

Nang Le Duc