I am moving my app to jetpack compose from view. The default navigation is using the nav_graph
. The app has been built following the principle of one activity, multiple fragments. In order to move the app slowly, I am trying to just load the compose in the fragment. so the fragment can be seen as a nest for compose. I am doing it for to keep the navigation in place prior to moving the navigation. I am trying to make compose to navigate to the fragment using the nav_graph.
Currently, my fragment looks like this:
SignInFragment:
class SignInFragment : BaseFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val composeView = ComposeView(requireContext())
composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
activity?.let {
SignInScreen()
}
}
}
return composeView
}
}
and I am trying to navigate to the HomeFragment
. Currently, I was using the navigation as below:
findNavController().navigate(SignInFragmentDirections.actionSignInFragmentToHomeFragment())
Now my composable is as below:
@Composable
fun SignInScreen(authViewModel: AuthViewModel = viewModel())
{
val authState by authViewModel.authState.collectAsState()
val lifecycleEventObserver = remember {
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
authViewModel.checkAuthorized()
}
}
}
ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleEventObserver)
if(authState is AuthUIState.LoginSuccess) {
navigateToDashboard()
}
Button(
onClick = { authViewModel.signIn() },
) {
Text("SignIn")
}
}
fun navigateToDashboard() {
// Try to navigate to home fragment
}
Basically when I am loading SignInScreen
, I am checking the state of the authorization. If authorized, I am redirecting to the HomePage otherwise, I display the button for the user to signIn.
I cannot figure out a way to do the navigateToDashboard()
I am really trying to keep the fragment just for the nav_graph, so I can do the transition when all screens are in Compose.
any idea?
Let your fragments do the navigation as before.
Pass a callback function as parameter from fragment to compose.
So base on your code, change SignInFragment like this:
class SignInFragment : BaseFragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val composeView = ComposeView(requireContext())
composeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
activity?.let {
SignInScreen(
navigateToDashboard = ::navigateToDashboard
)
}
}
}
return composeView
}
fun navigateToDashboard(){
findNavController().navigate(SignInFragmentDirections.actionSignInFragmentToDashboardFragment())
}
}
And SignInScreen:
@Composable
fun SignInScreen(
authViewModel: AuthViewModel = viewModel(),
navigateToDashboard:()->Unit,
){
val authState by authViewModel.authState.collectAsState()
val lifecycleEventObserver = remember {
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
authViewModel.checkAuthorized()
}
}
}
ProcessLifecycleOwner.get().lifecycle.addObserver(lifecycleEventObserver)
if(authState is AuthUIState.LoginSuccess) {
navigateToDashboard()
}
Button(
onClick = { authViewModel.signIn() },
) {
Text("SignIn")
}
}
Hope it helps.