5

So what I am trying to achieve is:

  • A home composable that hosts a BottomNav Bar (Scaffold is used here )
  • Bottom Nav Bar is attached with 3 other composables
  • Each of the 3 composables has its own lazy column
  • Every item in the 3 lazy columns have a menu icon which when clicked opens the bottom sheet

I was able to achieve the above by enclosing the scaffold inside a ModalBottonSheetLayout with the help of this answer here: Jetpack Compose Scaffold + Modal Bottom Sheet

The issue:

  • The purpose of the bottom sheet is to show a menu item which when clicked should delete the item from the lazyColumn
  • so the bottom sheet needs to know the details of the item that was clicked to delete it

How can I achieve that? The home composable does not have any information about the items inside the lazy columns present in the composables that it hosts.

Is there a different way to approach this?

Here is my code:

HomeComposable.kt

fun HomeComposable(homeViewModel: HomeViewModel, 
     navController: NavHostController) {
        ModalBottomSheetLayout(
           sheetContent = {
           //get the id of the message here so it can be     
           //deleted
               Button(
                   text = "delete Message")
                   onClick = deleteMessage(message.id
               )
           }
) {
    Scaffold(
    content = {
    NavHost(navController = navController, startDestination = 
    WHATS_NEW_COMPOSABLE) {

          composable(MESSAGES_COMPOSABLE) {
            MessageItemsComposable(
                homeViewModel,
                navController,
                bottomSheetState
            )
          }
 
    }
  }  
)

MessageItemsComposable.kt

val messages : List<Messages> = getMessagesFromNetwork()

LazyColumn {
    items(messages) { message ->
    Row{
        Text(message.title)
        Icon(
            onClick = {
             bottomState.show()
             //show a bottom sheet with an option to delete                 
            }
        ) {

           //Draw the icon
           }
        }            
    }
}
Anudeep Ananth
  • 955
  • 1
  • 8
  • 30
  • Can you attach the code ? – Stefano Sansone Sep 08 '21 at 12:43
  • Hi @StefanoSansone, i have updated the question with my code – Anudeep Ananth Sep 13 '21 at 06:22
  • Were you able to solve this? – vn1gam Feb 20 '22 at 00:56
  • @vn1gam Yes I was able to solve it, the solution was quite a complex one though... So here is what I did: - Create a mutable variable in the NavGraph that holds the current value of the menu item clicked in one of the items clicked in the Lazy Columns(it will be a dummy value when initialized) - Pass this variable as a parameter to the respective composables - populate this value when the menu item was clicked in the LC - Now the NavGraph has the correct value populated in the variable - The bottom sheet can now show a menu and perform logic for this specific item Hope this helps... – Anudeep Ananth Feb 21 '22 at 02:34

1 Answers1

1

For that case, I would use a repository with a StateFlow. This repository would be a singleton and it's responsible of maintaining data and deleting them. Your composable list will listen to state changes and your bottomsheet will call delete() to delete the selected element.

class Repository<T> {
    private val _state = MutableStateFlow<T>(initialState)
    val state: StateFlow<T> = _state

    fun delete(data: T) {
        _state.remove(data)
    }
}

The parent of you composable list should provide a callback. This callback should be invoked when the user clicks on a list item and that item is passed as parameter.

@Composable
fun DataList(onItemClick(item: T)) {
    // list implementation with onItemCkick as onClick callback
}

When invoked, you can open the bottomsheet and pass the item to it.

Thaerith
  • 697
  • 4
  • 13
  • Hi, i need your help, and this is what i'm searching for. I have 8 button and 1 bottomSheet, how can i change the texte of a button when i'm clicking a text in bottomSheet. The issue is that the bottomSheet doesn't know whick button was clicked – Mehdi.ncb Oct 01 '21 at 20:52
  • Hi, I think it is better to open a question to have more context. But from what I understand, you must pass a callback to the bottom sheet to notify the button with the new text and eventually a list a text to show in the bottom sheet. Based on the button clicked, you invoke the bottom sheet with different callback and text list. – Thaerith Oct 02 '21 at 17:18