Change the back stack system.
This commit is contained in:
		
							parent
							
								
									4b5893cf43
								
							
						
					
					
						commit
						d2acbf8d18
					
				
					 6 changed files with 63 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -13,7 +13,7 @@ import com.pixelized.biblib.ui.composable.screen.LoginScreenComposable
 | 
			
		|||
import com.pixelized.biblib.ui.composable.screen.MainScreenComposable
 | 
			
		||||
import com.pixelized.biblib.ui.composable.screen.SplashScreenComposable
 | 
			
		||||
import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Screen
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Screen
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
 | 
			
		||||
 | 
			
		||||
class MainActivity : ComponentActivity() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@ import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
 | 
			
		|||
import com.pixelized.biblib.ui.viewmodel.credential.CredentialViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.credential.ICredentialViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Screen
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
 | 
			
		||||
import kotlinx.coroutines.delay
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +216,7 @@ private fun LoginScreenNavigationComposable(
 | 
			
		|||
 | 
			
		||||
    val bookLoadingState by bookViewModel.state.observeAsState()
 | 
			
		||||
    if (bookLoadingState is IBooksViewModel.State.Finished) {
 | 
			
		||||
        navigationViewModel.navigateTo(INavigationViewModel.Screen.MainScreen)
 | 
			
		||||
        navigationViewModel.navigateTo(Screen.MainScreen)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ import com.pixelized.biblib.ui.theme.BibLibTheme
 | 
			
		|||
import com.pixelized.biblib.ui.viewmodel.book.BooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Page
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Page
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
 | 
			
		||||
 | 
			
		||||
@Preview
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,7 @@ import com.pixelized.biblib.ui.viewmodel.authentication.IAuthenticationViewModel
 | 
			
		|||
import com.pixelized.biblib.ui.viewmodel.book.BooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.book.IBooksViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Screen
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.NavigationViewModel
 | 
			
		||||
import kotlinx.coroutines.delay
 | 
			
		||||
import java.util.*
 | 
			
		||||
| 
						 | 
				
			
			@ -85,14 +86,14 @@ fun SplashScreenComposable(
 | 
			
		|||
                LaunchedEffect(LAUNCH_EFFECT_NAVIGATION) {
 | 
			
		||||
                    contentVisible.value = false
 | 
			
		||||
                    delay(1000)
 | 
			
		||||
                    navigationViewModel.navigateTo(INavigationViewModel.Screen.MainScreen)
 | 
			
		||||
                    navigationViewModel.navigateTo(Screen.MainScreen)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            LaunchedEffect(LAUNCH_EFFECT_NAVIGATION) {
 | 
			
		||||
                contentVisible.value = false
 | 
			
		||||
                delay(1000)
 | 
			
		||||
                navigationViewModel.navigateTo(INavigationViewModel.Screen.LoginScreen)
 | 
			
		||||
                navigationViewModel.navigateTo(Screen.LoginScreen)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,31 +5,33 @@ import androidx.lifecycle.MutableLiveData
 | 
			
		|||
import com.pixelized.biblib.ui.data.BookUio
 | 
			
		||||
 | 
			
		||||
interface INavigationViewModel {
 | 
			
		||||
    val screen: LiveData<Screen>
 | 
			
		||||
    val page: LiveData<Page>
 | 
			
		||||
 | 
			
		||||
    fun navigateTo(screen: Screen): Boolean
 | 
			
		||||
    fun navigateTo(page: Page): Boolean
 | 
			
		||||
    val screen: LiveData<Navigable.Screen>
 | 
			
		||||
    val page: LiveData<Navigable.Page>
 | 
			
		||||
 | 
			
		||||
    fun navigateTo(navigable: Navigable, addToBackStack: Boolean = false): Boolean
 | 
			
		||||
    fun navigateBack(): Boolean
 | 
			
		||||
 | 
			
		||||
    sealed class Screen {
 | 
			
		||||
        object SplashScreen : Screen()
 | 
			
		||||
        object MainScreen : Screen()
 | 
			
		||||
        object LoginScreen : Screen()
 | 
			
		||||
    sealed class Navigable {
 | 
			
		||||
        sealed class Screen : Navigable() {
 | 
			
		||||
            object SplashScreen : Screen()
 | 
			
		||||
            object MainScreen : Screen()
 | 
			
		||||
            object LoginScreen : Screen()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sealed class Page : Navigable() {
 | 
			
		||||
            object HomePage : Page()
 | 
			
		||||
            data class Detail(val book: BookUio) : Page()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sealed class Page {
 | 
			
		||||
        object HomePage : Page()
 | 
			
		||||
        data class Detail(val book: BookUio) : Page()
 | 
			
		||||
    }
 | 
			
		||||
    class Mock(
 | 
			
		||||
        screen: Navigable.Screen = Navigable.Screen.SplashScreen,
 | 
			
		||||
        page: Navigable.Page = Navigable.Page.HomePage
 | 
			
		||||
    ) : INavigationViewModel {
 | 
			
		||||
        override val screen: LiveData<Navigable.Screen> = MutableLiveData(screen)
 | 
			
		||||
        override val page: LiveData<Navigable.Page> = MutableLiveData(page)
 | 
			
		||||
 | 
			
		||||
    class Mock(screen: Screen = Screen.SplashScreen, page: Page = Page.HomePage) : INavigationViewModel {
 | 
			
		||||
        override val screen: LiveData<Screen> = MutableLiveData(screen)
 | 
			
		||||
        override val page: LiveData<Page> = MutableLiveData(page)
 | 
			
		||||
 | 
			
		||||
        override fun navigateTo(screen: Screen): Boolean = false
 | 
			
		||||
        override fun navigateTo(page: Page): Boolean = false
 | 
			
		||||
        override fun navigateTo(navigable: Navigable, addToBackStack: Boolean): Boolean = false
 | 
			
		||||
        override fun navigateBack(): Boolean = false
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,38 +3,53 @@ package com.pixelized.biblib.ui.viewmodel.navigation
 | 
			
		|||
import androidx.lifecycle.LiveData
 | 
			
		||||
import androidx.lifecycle.MutableLiveData
 | 
			
		||||
import androidx.lifecycle.ViewModel
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Page
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Screen
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Page
 | 
			
		||||
import com.pixelized.biblib.ui.viewmodel.navigation.INavigationViewModel.Navigable.Screen
 | 
			
		||||
import java.util.*
 | 
			
		||||
 | 
			
		||||
class NavigationViewModel : ViewModel(), INavigationViewModel {
 | 
			
		||||
 | 
			
		||||
    private val stack = Stack<Page>()
 | 
			
		||||
 | 
			
		||||
    private val stack = Stack<Navigable?>()
 | 
			
		||||
    private val _screen = MutableLiveData<Screen>(Screen.SplashScreen)
 | 
			
		||||
    override val screen: LiveData<Screen> get() = _screen
 | 
			
		||||
 | 
			
		||||
    private val _page = MutableLiveData<Page>(Page.HomePage)
 | 
			
		||||
 | 
			
		||||
    override val screen: LiveData<Screen> get() = _screen
 | 
			
		||||
    override val page: LiveData<Page> get() = _page
 | 
			
		||||
 | 
			
		||||
    override fun navigateTo(screen: Screen): Boolean {
 | 
			
		||||
        _screen.postValue(screen)
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun navigateTo(page: Page): Boolean {
 | 
			
		||||
        _page.postValue(page)
 | 
			
		||||
        stack.push(page)
 | 
			
		||||
    override fun navigateTo(navigable: Navigable, addToBackStack: Boolean): Boolean {
 | 
			
		||||
        when (navigable) {
 | 
			
		||||
            is Page -> _page.postValue(navigable)
 | 
			
		||||
            is Screen -> _screen.postValue(navigable)
 | 
			
		||||
        }
 | 
			
		||||
        if (addToBackStack) {
 | 
			
		||||
            stack.push(navigable)
 | 
			
		||||
        } else {
 | 
			
		||||
            stack.push(null)
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun navigateBack(): Boolean {
 | 
			
		||||
        stack.pop()
 | 
			
		||||
        return if (stack.empty()) {
 | 
			
		||||
            false
 | 
			
		||||
        return when (val navigable: Navigable? = popBackStack()) {
 | 
			
		||||
            is Page -> {
 | 
			
		||||
                _page.postValue(navigable)
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            is Screen -> {
 | 
			
		||||
                _screen.postValue(navigable)
 | 
			
		||||
                true
 | 
			
		||||
            }
 | 
			
		||||
            else -> false
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun popBackStack(): Navigable? {
 | 
			
		||||
        return if (stack.isEmpty()) {
 | 
			
		||||
            null
 | 
			
		||||
        } else {
 | 
			
		||||
            _page.postValue(stack.peek())
 | 
			
		||||
            true
 | 
			
		||||
            stack.pop()
 | 
			
		||||
            while (stack.isNotEmpty() && stack.peek() == null) stack.pop()
 | 
			
		||||
            return if (stack.isNotEmpty()) stack.peek() else null
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue