2

I have an activity that has a list of items loaded through the Paging 3 library. The list screen is designed by using jetpack compose and the list of items is shown in a Lazy column.

Clicking on any list item would take me to a detailed screen and some manipulations happen there. On clicking back, I'm unable to update my list item with an updated value, since LazyPagingItems has an immutable list. Any help is deeply appreciated.

  val lazyPagingEventList : LazyPagingItems<Event>= viewModel.getEventList()
            .collectAsLazyPagingItems()

    LazyColumn(modifier = Modifier
        .padding(horizontal = 8.dp),
        content = {

            itemsIndexed(items = lazyPagingEventList,
                key = { index, item ->
                    item.id
                },
                itemContent = { index, item ->

                   //displays each item
                   EventItem(value = item, onItemClicked = { item ->
                        val intent = Intent(context, EventDetails::class.java)
                        intent.putExtra("eventId",item.id) 
                        activityResult.launch(intent)                       
                   })
                })
            }
         )


   //activity result handle 
   val activityResult = rememberLauncherForActivityResult(
        contract = ActivityResultContracts.StartActivityForResult(),
        onResult = { activityResult ->

            if (activityResult.resultCode == ACTIVITY_SUCCESS) {
                activityResult.data?.let { intent ->

                    if (intent.hasExtra(EVENT_ID)) {

                        val eventId = intent.getIntExtra(EVENT_ID, 0)
                        val updatedPrice =
                            intent.getStringExtra(TRADE_PRICE) ?: EMPTY_STRING
  
                        val index = lazyPagingEventList.itemSnapshotList
                         .indexOf(lazyPagingEventList.itemSnapshotList.find { it.id == 
                           eventId })
                        
                        /*
                         below line is not working since itemSnapshotList.items is not 
                         a mutable list
                        */                         
                        lazyPagingEventList.itemSnapshotList.items[index] = 
                        lazyPagingEventList.itemSnapshotList.items[index].copy(price = 
                         updatedPrice) 

                         }
                     }
                 }
            } 
    )
Vikram Ragu
  • 169
  • 1
  • 8

2 Answers2

0

You should not mutate paging items directly rather you should update the source of data and then call invalidate on the paging source. If you are using room for local data storage or as a cache, you should update the data in the source and room will automatically invalidate the paging source for you and update the data. Its not a good practice to mutate data directly.

If you want to refresh whole data, then use refresh() method on LazyPagingItems.

  • Hi, on calling either refresh() or invalidate(), updates the entire list and my state is lost. For instance, If I have 5 pages loaded & if we call invalidate() or refresh(), everything is lost and I'm back to page 1, My intention is to update only one item in the list. To confirm things, I'm not using room DB for local data storage. – Vikram Ragu Oct 10 '22 at 18:10
  • @VikramRagu were you able to solve this ? – Faraz Ahmed Jun 05 '23 at 11:20
  • @FarazAhmed, I have posted the answer below and that's how I was able to solve it. Though it could be a temporary work around. – Vikram Ragu Jul 04 '23 at 19:17
0

I made the data class arguments mutable (var instead of val) and I mutate the value on the activity result and it worked.

 if (activityResult.resultCode == ACTIVITY_SUCCESS) {
       activityResult.data?.let { intent ->

        if (intent.hasExtra(EVENT_ID)) {

           val eventId = intent.getIntExtra(EVENT_ID, 0)
           val updatedPrice =
              intent.getStringExtra(TRADE_PRICE) ?: EMPTY_STRING

           val index = lazyPagingEventList.itemSnapshotList
                 .indexOf(lazyPagingEventList.itemSnapshotList.find { 
                 it.id == eventId })
                    
                     
           lazyPagingEventList.itemSnapshotList.items[index].price 
                    = updatedPrice

                    }
               }
          }
Vikram Ragu
  • 169
  • 1
  • 8