https://kotlinlang.org logo
#compose
Title
# compose
l

Lokik Soni

02/18/2022, 11:13 AM
Hi all, I am working with Jetpack compose and not able to use ViewModel properly. Here is problem: I Know we can not @inject a class inside @composable function so I decided to @Inject BatteryBroadcast class in MainActivity and pass data from that class to the ViewModel.
Copy code
@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject
    lateinit var batteryBroadcast: BatteryBroadcast

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContent {
            BatteryAlarmGoldTheme {

                val homeViewModel = hiltViewModel<HomeViewModel>()
                lifecycle.addObserver(batteryBroadcast)
                homeViewModel.setBatteryProfileData(batteryBroadcast.dataFlow)

                // A surface container using the 'background' color from the theme
                Surface(color = MaterialTheme.colors.background) {
                    BatteryAlarmGoldApp()
                }
            }
        }
    }
}
Now I want to use the same ViewModel in my compose to access that data. I am using NavHost for that currently
Copy code
fun NavGraphBuilder.homeNavGraph(
    navController: NavHostController
) {
    navigation(startDestination = Screen.HomeScreen.route, route = HOME_ROUTE) {
        composable(Screen.HomeScreen.route) {
            val homeBackStackEntry = remember { navController.getBackStackEntry(HOME_ROUTE) }
            val homeViewModel: HomeViewModel = hiltViewModel(homeBackStackEntry)

            HomeScreen(
                navController = navController,
                viewModel = homeViewModel
            )
        }
        composable(Screen.SelectRingtoneScreen.route) {
            val homeBackStackEntry = remember { navController.getBackStackEntry(HOME_ROUTE) }
            val homeViewModel: HomeViewModel = hiltViewModel(homeBackStackEntry)

            RingtoneScreen(
                viewModel = homeViewModel
            )
        }
    }
}
Or there is any batter solution to achieve the same please suggest me.
m

Marcello Galhardo

02/18/2022, 12:35 PM
Your first VM is scoped in the Activity, the second is scoped on the BackStackEntry - that won’t do what you want. I guess what you are looking for is to make the Battery Broadcast scope to be a Singleton and simple allow it to be injected in any ViewModel. The Battery Broadcast would expose a flow that can collected by any observer to react to it. That way you can collect it on the ViewModel init block or from the Composable by directly calling a callback from the VM with a LaunchedEffect. If you have a Single Activity architecture, the Battery Broadcast can connect to the Activity and communicate with the Activity by using Flows or Channels (depending on the need).
l

Lokik Soni

02/19/2022, 5:03 AM
Its worked thanks
👍 1