I am making a simple music player app, I'm trying to learn jetpack compose. I want to make an overlay view that will show over all the other app screens, similar to floating action button. This view has a progress bar showing the audio playing progress. I have achieved this with the code bellow..
@Composable
fun AppNavHost(
openAudioFile: (path: String) -> Unit,
playPauseClick: () -> Unit,
stopPlayingClick: () -> Unit,
state: State<AppScreenState>
) {
val audioFileState = state.value.audioFileState
val snackBarHostState = remember { SnackbarHostState() }
Scaffold(
snackbarHost = {
SnackbarHost(hostState = snackBarHostState)
},
floatingActionButton = {
if (audioFileState != AudioFileState.IDLE && audioFileState != AudioFileState.STOPED)
AppPlayerBar(
state.value,
playPauseClick = playPauseClick,
stopPlayingClick = stopPlayingClick
)
}
) { contentPadding ->
val navController = rememberNavController()
NavHost(
navController = navController,
startDestination = Screen.MusicFoldersScreen.route,
modifier = Modifier.padding(contentPadding)
) {
composable(
route = Screen.MusicFoldersScreen.route + "?path={path}",
arguments = listOf(navArgument(name = "path") {
type = NavType.StringType
defaultValue = ""
})
) { backStackEntry ->
val navArgs = backStackEntry.arguments
var path = ""
navArgs?.getString("path")?.let {
path = it
}
val musicViewModel = hiltViewModel<MusicFoldersViewModel>()
if (path.isBlank()) {
musicViewModel.loadMusicFolders()
} else {
musicViewModel.loadMusicFilesFromPath(path)
}
MusicFoldersScreen(
musicFolders = musicViewModel.musicFoldersState.collectAsState(
initial = emptyList()
)
) { newPath ->
if (newPath.endsWith(".mp3") || newPath.endsWith(".m4a")) {
openAudioFile(newPath)
return@MusicFoldersScreen
} else {
navController.navigate(Screen.MusicFoldersScreen.route + "?path=$newPath")
}
}
}
}
}
}
Another component in my app changes the state.audioFileProgress . The AudioFileState is a data class defined like this: data class AppScreenState(var audioFileState: AudioFileState, var audioFileProgress: Float)
The problem is that the Scaffold content (NavHost) is recomposed. I don't know why. It doesn't uses the state object
Update: I resolved the problem by moving
val audioFileState = state.value.audioFileStateintofloatingActionButtoncontent like this:Now only the
floatingActionButtonis recomposed.