Skip to content

Commit

Permalink
#3 - 화면 전환 graph 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
sksowk156 committed Dec 11, 2024
1 parent a6f584e commit 463d919
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 132 deletions.
22 changes: 11 additions & 11 deletions app/src/main/java/com/yapp/chaeum/navigation/AppNavHost.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ package com.yapp.chaeum.navigation
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import com.example.auth.navigation.AuthRoute
import com.example.auth.navigation.authScreen
import com.example.etc.navigation.etcScreen
import com.example.matching.navigation.matchingScreen
import com.example.mypage.navigation.myPageScreen
import androidx.navigation.compose.composable
import com.example.auth.navigation.AuthGraph
import com.example.auth.navigation.authNavGraph
import com.yapp.chaeum.ui.AppState
import com.yapp.chaeum.ui.HomeGraph
import com.yapp.chaeum.ui.HomeRoute

@Composable
fun AppNavHost(
Expand All @@ -18,14 +18,14 @@ fun AppNavHost(
val navController = appState.navController
NavHost(
navController = navController,
startDestination = AuthRoute,
startDestination = AuthGraph,
modifier = modifier,
) {
authScreen(
authNavGraph(
onLoginSuccess = { appState.loginSuccess() },
)
matchingScreen()
myPageScreen()
etcScreen()
composable<HomeGraph> {
HomeRoute()
}
}
}
}
26 changes: 26 additions & 0 deletions app/src/main/java/com/yapp/chaeum/navigation/HomeNavHost.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.yapp.chaeum.navigation

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import com.example.etc.navigation.etcScreen
import com.example.matching.navigation.MatchingGraph
import com.example.matching.navigation.matchingNavGraph
import com.example.mypage.navigation.myPageScreen

@Composable
fun HomeNavHost(
navController: NavHostController,
modifier: Modifier = Modifier,
) {
NavHost(
navController = navController,
startDestination = MatchingGraph,
modifier = modifier,
) {
matchingNavGraph()
myPageScreen()
etcScreen()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import androidx.compose.material.icons.filled.Call
import androidx.compose.material.icons.outlined.Call
import androidx.compose.ui.graphics.vector.ImageVector
import com.example.etc.navigation.EtcRoute
import com.example.matching.navigation.MatchingRoute
import com.example.matching.navigation.MatchingGraphDest
import com.example.mypage.navigation.MyPageRoute
import kotlin.reflect.KClass

Expand All @@ -21,7 +21,7 @@ enum class TopLevelDestination(
unselectedIcon = Icons.Outlined.Call,
iconText = "매칭",
titleText = "매칭",
route = MatchingRoute::class,
route = MatchingGraphDest.MatchingRoute::class,
),
MYPAGE(
selectedIcon = Icons.Filled.Call,
Expand Down
61 changes: 3 additions & 58 deletions app/src/main/java/com/yapp/chaeum/ui/App.kt
Original file line number Diff line number Diff line change
@@ -1,66 +1,11 @@
package com.yapp.chaeum.ui

import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.navigation.NavDestination
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.compose.currentBackStackEntryAsState
import com.yapp.chaeum.navigation.AppNavHost
import com.yapp.chaeum.navigation.TopLevelDestination
import kotlin.reflect.KClass

@Composable
fun App(appState: AppState = rememberAppState()) {
val navBackStackEntry by appState.navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination

// 현재 화면이 TopLevelDestination 중 하나인지 확인
val isTopLevel = TopLevelDestination.entries.any {
currentDestination?.route == it.route.qualifiedName
}

Scaffold(
bottomBar = {
if (isTopLevel) {
BottomNavigation(
modifier = Modifier.navigationBarsPadding()
) {
TopLevelDestination.entries.forEach { topLevelRoute ->
BottomNavigationItem(
icon = {
Icon(
topLevelRoute.selectedIcon,
contentDescription = topLevelRoute.name
)
},
label = { Text(topLevelRoute.name) },
selected = currentDestination?.hierarchy?.any { destination ->
destination.route == topLevelRoute.route.qualifiedName
} == true,
onClick = {
appState.navigateToTopLevelDestination(topLevelRoute)
}
)
}
}
}
}
) { innerPadding ->
AppNavHost(
appState = appState,
modifier = Modifier.padding(innerPadding)
)
}
AppNavHost(
appState = appState,
)
}

private fun NavDestination.hasRoute(routeClass: KClass<*>): Boolean {
return this.route == routeClass.qualifiedName
}
51 changes: 5 additions & 46 deletions app/src/main/java/com/yapp/chaeum/ui/AppState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,66 +5,25 @@ import androidx.compose.runtime.remember
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.example.auth.navigation.AuthRoute
import com.example.auth.navigation.navigateToAuth
import com.example.etc.navigation.navigateToEtc
import com.example.matching.navigation.MatchingRoute
import com.example.matching.navigation.navigateToMatching
import com.example.mypage.navigation.navigateToMyPage
import com.yapp.chaeum.navigation.TopLevelDestination

@Composable
fun rememberAppState(
navController: NavHostController = rememberNavController(),
): AppState {
return remember(
navController,
) {
AppState(
navController = navController,
)
return remember(navController) {
AppState(navController = navController)
}
}

class AppState(
val navController: NavHostController,
) {
fun navigateToTopLevelDestination(topLevelDestination: TopLevelDestination) {
val topLevelNavOptions = navOptions {
fun loginSuccess() {
navController.navigate(HomeGraph) {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
inclusive = true
}
launchSingleTop = true
restoreState = true
}

when (topLevelDestination) {
TopLevelDestination.MATCHING -> navController.navigateToMatching(topLevelNavOptions)
TopLevelDestination.MYPAGE -> navController.navigateToMyPage(topLevelNavOptions)
TopLevelDestination.ETC -> navController.navigateToEtc(topLevelNavOptions)
}
}

fun navigateBack() {
navController.popBackStack()
}

fun logout() {
navController.navigateToAuth(
navOptions {
popUpTo(navController.graph.findStartDestination().id) {
inclusive = true
}
launchSingleTop = true
}
)
}

fun loginSuccess() {
navController.navigate(MatchingRoute) {
popUpTo(AuthRoute) { inclusive = true }
launchSingleTop = true
}
}
}
65 changes: 65 additions & 0 deletions app/src/main/java/com/yapp/chaeum/ui/HomeRoute.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package com.yapp.chaeum.ui

import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material.BottomNavigation
import androidx.compose.material.BottomNavigationItem
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.compose.currentBackStackEntryAsState
import com.yapp.chaeum.navigation.HomeNavHost
import com.yapp.chaeum.navigation.TopLevelDestination
import kotlinx.serialization.Serializable

@Serializable
data object HomeGraph

@Composable
fun HomeRoute(
homeState: HomeState = rememberHomeState()
) {
Scaffold(
bottomBar = {
HomeBottomBar(homeState)
}
) { innerPadding ->
HomeNavHost(
navController = homeState.navController,
modifier = Modifier.padding(innerPadding)
)
}
}

@Composable
private fun HomeBottomBar(
homeState: HomeState,
) {
val navBackStackEntry by homeState.navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
BottomNavigation(
modifier = Modifier.navigationBarsPadding()
) {
TopLevelDestination.entries.forEach { topLevelRoute ->
BottomNavigationItem(
icon = {
Icon(
imageVector = topLevelRoute.selectedIcon,
contentDescription = topLevelRoute.name
)
},
label = { Text(topLevelRoute.name) },
selected = currentDestination?.hierarchy?.any { destination ->
destination.route == topLevelRoute.route.qualifiedName
} == true,
onClick = {
homeState.navigateToTopLevelDestination(topLevelRoute)
}
)
}
}
}
41 changes: 41 additions & 0 deletions app/src/main/java/com/yapp/chaeum/ui/HomeState.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.yapp.chaeum.ui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.example.etc.navigation.navigateToEtc
import com.example.matching.navigation.navigateToMatching
import com.example.mypage.navigation.navigateToMyPage
import com.yapp.chaeum.navigation.TopLevelDestination

@Composable
fun rememberHomeState(
navController: NavHostController = rememberNavController(),
): HomeState {
return remember(navController) {
HomeState(navController = navController)
}
}

class HomeState(
val navController: NavHostController,
) {
fun navigateToTopLevelDestination(topLevelDestination: TopLevelDestination) {
val topLevelNavOptions = navOptions {
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}

when (topLevelDestination) {
TopLevelDestination.MATCHING -> navController.navigateToMatching(topLevelNavOptions)
TopLevelDestination.MYPAGE -> navController.navigateToMyPage(topLevelNavOptions)
TopLevelDestination.ETC -> navController.navigateToEtc(topLevelNavOptions)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,29 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import androidx.navigation.navigation
import com.example.auth.AuthRoute
import kotlinx.serialization.Serializable

@Serializable
object AuthRoute
data object AuthGraph

sealed class AuthGraphDest {
@Serializable
data object AuthRoute : AuthGraphDest()
}

fun NavController.navigateToAuth(navOptions: NavOptions) =
navigate(route = AuthRoute, navOptions)
navigate(route = AuthGraphDest.AuthRoute, navOptions)

fun NavGraphBuilder.authScreen(
onLoginSuccess: () -> Unit
fun NavGraphBuilder.authNavGraph(
onLoginSuccess: () -> Unit,
) {
composable<AuthRoute> {
AuthRoute(
onLoginSuccess = onLoginSuccess
)
navigation<AuthGraph>(startDestination = AuthGraphDest.AuthRoute) {
composable<AuthGraphDest.AuthRoute> {
AuthRoute(
onLoginSuccess = onLoginSuccess
)
}
}
}
}
Loading

0 comments on commit 463d919

Please sign in to comment.