package com.aiosman.riderpro import ModificationListScreen import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.navigationBars import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.NavigationBarItemColors import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Tab import androidx.compose.material3.TabRow import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import androidx.navigation.NavGraph import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.aiosman.riderpro.ui.theme.RiderProTheme import com.google.accompanist.systemuicontroller.rememberSystemUiController import com.google.android.libraries.places.api.Places import kotlinx.coroutines.launch class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) if (!Places.isInitialized()) { Places.initialize(applicationContext, "AIzaSyDpgLDH1-SECw_pdjJq_msynq1XrxwgKVI") } enableEdgeToEdge() setContent { Navigation() } } } val LocalNavController = compositionLocalOf { error("NavController not provided") } @Composable fun NavigationController(navController: NavHostController) { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } NavHost( navController = navController, startDestination = NavigationItem.Home.route, ) { // 带底部导航栏的路由: listOf( NavigationItem.Home, NavigationItem.Street, NavigationItem.Add, NavigationItem.Message, NavigationItem.Profile ).forEach { item -> composable(route = item.route) { ScaffoldWithNavigationBar(navController) { when (item) { NavigationItem.Home -> Home() NavigationItem.Street -> Street() NavigationItem.Add -> Add() NavigationItem.Message -> Video() NavigationItem.Profile -> Profile() else -> {} // 由于过滤,这里不会发生 } } } } composable(route = "ProfileTimeline") { GalleryPage() } composable(route = "LocationDetail") { Box( modifier = Modifier.padding(bottom = navigationBarHeight) ) { LocationDetail() } } composable(route = "OfficialPhoto") { OfficialGalleryPage() } composable(route = "OfficialPhotographer") { OfficialPhotographer() } composable(route = "Post") { Box( modifier = Modifier.padding(bottom = navigationBarHeight) ) { PostPage() } } composable(route = "ModificationList") { ModificationListScreen() } composable(route = "MyMessage") { NotificationsScreen() } composable(route = "Comments") { CommentsScreen() } composable(route = "Likes") { LikePage() } composable(route = "Followers") { FollowerPage() } composable(route = "NewPost") { NewPostScreen() } composable(route = "EditModification") { Box( modifier = Modifier.padding(top = 64.dp) ) { EditModification() } } } } @Composable fun Navigation() { val navController = rememberNavController() CompositionLocalProvider(LocalNavController provides navController) { Box { NavigationController(navController = navController) } } } // 用于带导航栏的路由的可复用 composable @Composable fun ScaffoldWithNavigationBar( navController: NavHostController, content: @Composable () -> Unit ) { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } val item = listOf( NavigationItem.Home, NavigationItem.Street, NavigationItem.Add, NavigationItem.Message, NavigationItem.Profile ) Scaffold( modifier = Modifier.statusBarsPadding(), bottomBar = { NavigationBar( modifier = Modifier.height(56.dp + navigationBarHeight), containerColor = Color.Black ) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route val systemUiController = rememberSystemUiController() item.forEach { it -> NavigationBarItem( selected = currentRoute == it.route, onClick = { // Check if the current route is not the same as the tab's route to avoid unnecessary navigation if (currentRoute != it.route) { navController.navigate(it.route) { // Avoid creating a new layer on top of the navigation stack launchSingleTop = true // Attempt to pop up to the existing instance of the destination, if present popUpTo(navController.graph.startDestinationId) { saveState = true } // Restore state when navigating back to the composable restoreState = true } } // Additional logic for system UI color changes when (it.route) { NavigationItem.Add.route -> { systemUiController.setSystemBarsColor(color = Color.Black) } NavigationItem.Message.route -> { systemUiController.setSystemBarsColor(color = Color.Black) } else -> { systemUiController.setSystemBarsColor(color = Color.Transparent) } } }, colors = NavigationBarItemColors( selectedIconColor = Color.Red, selectedTextColor = Color.Red, selectedIndicatorColor = Color.Black, unselectedIconColor = Color.Red, unselectedTextColor = Color.Red, disabledIconColor = Color.Red, disabledTextColor = Color.Red, ), icon = { Icon( modifier = Modifier.size(24.dp), imageVector = it.icon(), contentDescription = null, tint = if (currentRoute == it.route) Color.Red else Color.White ) } ) } } } ) { innerPadding -> Box( modifier = Modifier.padding(innerPadding) ) { content() } } } @Composable fun Home() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { PagingBackendSample() } } @Composable fun Street() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { StreetPage() } } @Composable fun Add() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize() .background(Color.Black), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { AddPage() } } @Composable fun Video() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, ) { ShortVideo() } } @Composable fun Message() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.Top, horizontalAlignment = Alignment.CenterHorizontally, ) { MessagePage() } } @Composable fun Profile() { val navigationBarHeight = with(LocalDensity.current) { WindowInsets.navigationBars.getBottom(this).toDp() } Column( modifier = Modifier .fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { ProfilePage() } } @Preview(showBackground = true) @Composable fun GreetingPreview() { RiderProTheme { Surface(modifier = Modifier.fillMaxSize(), color = Color.White) { Navigation() } } }