Cicero
08/11/2021, 2:32 PMCicero
08/11/2021, 2:32 PMclass MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
MainNavigation()
}
}
}
}
@Composable
fun MainNavigation() {
val navHostController = rememberNavController()
val mainActions = MainActions(
navController = navHostController,
destination = MainDestinations
)
AppTheme {
NavHost(
navController = navHostController,
startDestination = SPLASH
) {
composable(SPLASH) {
SplashView(mainActions)
}
composable(LOGIN) {
Login(mainActions)
}
}
}
}
object MainDestinations {
const val SPLASH = "SPLASH"
const val LOGIN = "LOGIN"
const val HOME = "HOME"
}
class MainActions(
private val navController: NavHostController,
private val destination: MainDestinations
) {
fun navigateTo(route: String){
navController.navigate(route){
popUpTo(SPLASH) { inclusive = true }
}
}
fun navigateHome(){
navController.navigate(destination.HOME)
}
}
Cicero
08/11/2021, 2:32 PMpackage de.cicerohellmann.jubilantOctoMemory.screens.splash
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import de.cicerohellmann.jubilantOctoMemory.MainActions
import org.koin.androidx.compose.getViewModel
@Composable
fun SplashView(
action: MainActions,
viewModel: SplashViewModel = getViewModel()
) {
val destination = viewModel.destination.observeAsState()
if(destination.value != null){
action.navigateTo(destination.value!!)
}
SplashUI()
}
@Composable
fun SplashUI(){
Column(modifier = Modifier.fillMaxSize()) {
}
}
@Preview
@Composable
fun SplashUIPreview(){
SplashUI()
}
Cicero
08/11/2021, 2:32 PMpackage de.cicerohellmann.jubilantOctoMemory.screens.splash
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.cicerohellmann.jubilantOctoMemory.extensions.immutable
import de.cicerohellmann.jubilantOctoMemory.usecase.GetStartingDestinationByUserIsLogged
import de.cicerohellmann.jubilantOctoMemory.usecase.ReadUserSortedByDateUseCase
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
class SplashViewModel(private val readUserSortedByDateUseCase: ReadUserSortedByDateUseCase) :
ViewModel() {
private val _destination = MutableLiveData<String?>(null)
val destination = _destination.immutable()
init {
viewModelScope.launch {
_destination.value = GetStartingDestinationByUserIsLogged().execute(readUserSortedByDateUseCase.execute())
}
}
}
Cicero
08/11/2021, 2:33 PMclass ReadUserSortedByDateUseCase(private val userDataSource: UserDataSource) {
fun execute(): User? {
return userDataSource.readUserFlow()
}
}
class GetStartingDestinationByUserIsLogged {
fun execute(user: User?): String {
user ?: return MainDestinations.LOGIN
return if (user.isLogged) {
MainDestinations.HOME
} else {
MainDestinations.LOGIN
}
}
}
Cicero
08/11/2021, 3:13 PMif (destination.value != null) {
LaunchedEffect(destination) {
action.navigateTo(destination.value!!)
}
}
Works but then the navigation method must be changed from popUpTo to simple navigation and the problem with this approach is that I will need to remove the Splash screen from the stack manually which I can't believe is the correct way.
fun navigateTo(route: String){
navController.navigate(route){
popUpTo(route) { inclusive = false }
}
}
to
fun navigateTo(route: String){
navController.navigate(route)
}
Cicero
08/11/2021, 3:18 PMfun navigateTo(route: String){
navController.navigate(route){
popUpTo(route) { inclusive = true }
}
}
When I finally in the login screen and press the back button, I still go back to the splash screen. I can't find the track of what is going wrong here.Cicero
08/11/2021, 3:19 PMCicero
08/11/2021, 3:33 PMCicero
08/11/2021, 3:37 PMPop up to a given destination before navigating. This pops all non-matching destinations from the back stack until this destination is found.
Colton Idle
08/11/2021, 3:39 PMCicero
08/11/2021, 3:41 PMCicero
08/11/2021, 3:52 PMfun popUpToFromSplashTo(route: String){
navController.navigate(route){
popUpTo(SPLASH) { inclusive = true }
}
}
And it happened that I just needed to update my compose navigation version.Cicero
08/11/2021, 3:53 PMCicero
08/11/2021, 3:59 PMIan Lake
08/11/2021, 4:45 PMnavigate
as part of composition is absolutely a side effect that you would never want to run every frame of an animationCicero
08/11/2021, 4:56 PMColton Idle
08/11/2021, 4:56 PMCicero
08/11/2021, 4:59 PMIan Lake
08/11/2021, 5:01 PMIan Lake
08/11/2021, 5:02 PMobserveAsState()
for events should have been your first red flag - state is safe to consume 100x over. Events are notCicero
08/11/2021, 5:05 PMCicero
08/11/2021, 5:06 PMColton Idle
08/11/2021, 5:06 PMCicero
08/11/2021, 5:06 PMColton Idle
08/11/2021, 5:07 PMCicero
08/11/2021, 5:08 PMCicero
08/11/2021, 5:11 PMColton Idle
08/11/2021, 5:19 PMIan Lake
08/11/2021, 5:22 PMColton Idle
08/11/2021, 5:37 PMIan Lake
08/11/2021, 5:39 PMIan Lake
08/11/2021, 5:40 PMCicero
08/11/2021, 8:33 PMCicero
08/11/2021, 9:30 PMTash
08/11/2021, 9:46 PMSnackbarHostState
are helpful https://developer.android.com/reference/kotlin/androidx/compose/material/SnackbarHostStateCicero
08/11/2021, 10:20 PMColton Idle
08/11/2021, 10:54 PM