0

I'm working on a simple SoundBoard app to get familiar with Jetpack Compose and Navigation. I'm fairly new to both technologies and am struggling with this:

Main view in the app is a grid-like view of all sounds that are stored in an SQLite database. Users can edit a sound to change its name in a dialog. When the edit dialog is closed, I want to refresh the grid, but I haven't found a way how this is implemented ideally.

Screenshot of the SoundBoard that displays sounds on a grid Screenshot of the SoundBoard grid with a edit dialog in foreground

So far, I have these destinations:

object Destinations {
    @Serializable
    object SoundGrid
    
    @Serializable
    class SoundEdit(val soundId: Int)
}

And use them like this:

@Composable
fun SoundBoardApp(navController: NavHostController = rememberNavController()) {
    NavHost(navController = navController, startDestination = SoundGrid) {
        composable<SoundGrid> {
            SoundGrid(
                onNavigateToSoundEdit = {
                    navController.navigate(SoundEdit(it.id))
                })
        }

        dialog<SoundEdit> {
            SoundEditDialog(onClose = {
                navController.navigateUp()
            })
        }
    }
}

@Composable
fun SoundGrid(
    onNavigateToSoundEdit: (Sound) -> Unit,
    modifier: Modifier = Modifier,
    viewModel: SoundGridViewModel = koinViewModel(),
) { .. }

@Composable
fun SoundEditDialog(
    onClose: () -> Unit,
    viewModel: SoundEditViewModel = koinViewModel()
) { .. }

How can I instruct the ViewModel of the SoundGrid composable to update the data when the dialog got closed? What is the ideal way of implementing this functionality?

4
  • Are you using an Android Room database? If yes, the ideal way would be to return a Kotlin Flow from your database so that any data changed will refresh the UI automatically. You can read more here: developer.android.com/training/data-storage/room/… This is a really nice-looking app by the way ;) Commented Nov 11, 2024 at 15:24
  • Thanks! Using a Flow provided by room works. What would be the solution if my data is provided by a REST API instead? Can't use a Flow in that case, if I'm not wrong? Commented Nov 11, 2024 at 16:14
  • One of the other options is using parent navigation or start destination scoped shared ViewModel. NavBackStackEntry is a ViewModelStoreOwner, so using any NavBackStackEntry you can get an ViewModel for different scoped to it. I don't know how it implemented with koin but with no injection viewModel(entry) or with dagger hilt you simply pass hitViewModel(entry) to get same ViewModel for different destinations with val entry = navController.getBackStackEntry(SoundGrid) Commented Nov 11, 2024 at 20:31
  • In case of networking operations, either use suspend functions that you can call from the viewModelScope in your ViewModel, then from the Composable call the ViewModel function. Or you could also look into callbackFlow, though I haven't used that myself yet. Commented Nov 12, 2024 at 7:25

0

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.