Home > OS >  How to use mutableStateListOf in compose
How to use mutableStateListOf in compose

Time:09-19

Items get displayed as duplicates when I use remember with mutableStateListOf. so whats the right way of creating a mutable list that can hold a list of data classes in a composable.

sample code:

@Composable
fun WallpapersDetailScreen{
   val items  =   remember {
        mutableStateListOf<MultiFabItem>() 
    } 

 items.addAll( listOf(
     MultiFabItem(
         identifier = FabIdentifier.FAVOURITE.name,
         icon = ImageBitmap.imageResource(id = R.drawable.heart),
         label = "favourite"
     ),

     MultiFabItem(
         identifier = FabIdentifier.SET_AS_WALLPAPER.name,
         icon = ImageBitmap.imageResource(id = R.drawable.wallpaper),
           label = "Set As Wallpaper"
         )
   )
    }
     

CodePudding user response:

You are adding item on each recomposition with

items.addAll( listOf(
     MultiFabItem(
         identifier = FabIdentifier.FAVOURITE.name,
         icon = ImageBitmap.imageResource(id = R.drawable.heart),
         label = "favourite"
     ),

     MultiFabItem(
         identifier = FabIdentifier.SET_AS_WALLPAPER.name,
         icon = ImageBitmap.imageResource(id = R.drawable.wallpaper),
           label = "Set As Wallpaper"
         )
   )

You can add your items inside remember only on composition and calling ImageBitmap.imageResource before adding to list. imageResource uses remember under the hood so you don't have to worry for re-instantiation of images

   val heartBitmap = ImageBitmap.imageResource(id = R.drawable.heart)
   val wallpaperBitmap = ImageBitmap.imageResource(id = R.drawable.wallpaper)

   val items = remember {
        mutableStateListOf<MultiFabItem>().apply{
            addAll( listOf(
         MultiFabItem(
             identifier = FabIdentifier.FAVOURITE.name,
             icon = heartBitmap,
             label = "favourite"
         ),
    
         MultiFabItem(
             identifier = FabIdentifier.SET_AS_WALLPAPER.name,
             icon = wallpaperBitmap,
               label = "Set As Wallpaper"
             )
       )
        } 
    } 

Other option is simply checking if items is empty if so add items then.

if (items.isEmpty()) {
    items.addAll(
        listOf(
            MultiFabItem(
                identifier = FabIdentifier.FAVOURITE.name,
                icon = ImageBitmap.imageResource(id = R.drawable.heart),
                label = "favourite"
            ),

            MultiFabItem(
                identifier = FabIdentifier.SET_AS_WALLPAPER.name,
                icon = ImageBitmap.imageResource(id = R.drawable.wallpaper),
                label = "Set As Wallpaper"
            )
        )
    )
}
  • Related