网站最新一次改版时间什么意思,徐州集团网站建设方案,网站 的版面结构,无极招聘网最新招聘在前一章节的实现中#xff0c;Skeleton: Main structure#xff0c;我们留下了几个 Jetpack 架构组件#xff0c;这些组件将在本章中使用#xff0c;例如 Composables、ViewModels、Navigation 和 Hilt。此外#xff0c;我们还通过 Scaffold 集成了 TopAppBar 和 BottomA…在前一章节的实现中Skeleton: Main structure我们留下了几个 Jetpack 架构组件这些组件将在本章中使用例如 Composables、ViewModels、Navigation 和 Hilt。此外我们还通过 Scaffold 集成了 TopAppBar 和 BottomAppBar UI 模式的基本结构。为了继续改进这个实现我们需要添加一个新的关键选项卡即“应用程序的通用状态”。
App程序的状态一般状态
定义导航地图
导航从其他UI元素
摘要 应用程序状态一个通用状态 “设计原则”中我们讨论了状态在现代 Android 应用程序中的重要作用。 设计中可能存在三种类型的状态属性 UI 状态、组件 UI 状态和屏幕 UI 状态。 除了这些状态之外我们还可以定义一种新类型的状态即应用程序状态。 这个新状态将定义应用程序的通用状态。它将用于屏幕之间的导航、自发消息snackbars的呈现以及应用程序中其他可用的进程。 在主目录中我们将定义一个名为 OrderNowState 的类它将是我们的状态持有者代表这种类型的状态。 接下来我们像这样执行OrderNowState的初始实现:
SuppressLint(RememberReturnType)
Composable
fun rememberAppState(scaffoldState:ScaffoldStaterememberScaffoldState(),navController: NavHostController rememberNavController(),resources1: Resources resources(),coroutineScope: CoroutineScoperememberCoroutineScope()
)remember(scaffoldState,navController,resources1,coroutineScope){OrderNowState(scaffoldState,navController,resources1,coroutineScope)
}class OrderNowState(val scaffoldState:ScaffoldState,val navController:NavHostController,private val resources:Resources,coroutineScope:CoroutineScope)Composable
ReadOnlyComposable
fun resources():Resources{LocalConfiguration.currentreturn LocalContext.current.resources
}然后我们修改我们的OrderNowScreen视图以包含之前定义的状态如下所示:
Preview
Composable
fun OrderNowScreen(){MyTestTheme {Surface(modifier Modifier.fillMaxSize(),colorMaterialTheme.colors.background) {val appState rememberAppState()Scaffold(scaffoldState appState.scaffoldState, topBar { OrderNowTopBar()}, bottomBar {OrderNowBottomBar()}){contentPadding-println(contentPadding)}}}
}注意:
还需要向OrderNowScreen添加资源函数它将使用该函数访问App资源。
突出显示更改的代码行如下: Scaffold(scaffoldState appState.scaffoldState,topBar { OrderNowTopBar() },bottomBar { OrderNowBottomBar() }) { contentPadding -println(contentPadding)}
有了上面的代码我们现在可以告诉Scaffold它应该把哪个状态作为引用:应用程序的状态。之后视图之间的导航操作、自发消息的呈现以及视图只把AppState作为真实源的其他独占任务都将被允许。
既然已经为APP定义了状态我们就可以继续实现APP的导航了。
定义导航地图
我们在应用程序中使用的导航策略由以下元素组成:
NavHost:它是负责在视图中显示导航结果的组件。导航的结果由NavigationController和导航图中给出的定义决定。
AppSoGraph:它是导航图的实现。它应该根据指定的路由将导航指向哪个视图或可组合对象。
屏幕路由:它们是可以通过导航到达的应用程序的不同屏幕。无论导航是从选项菜单、链接、按钮还是任何其他活动代理激活的都无关紧要。每个屏幕都有一个与之关联的唯一路由。
一般导航图 我们将继续在OrderNow中包含这些元素
OrderNowScreenRoute
首先创建一个名为common - navigation的新遍历目录。在这个包中我们像这样添加了一个名为OrderNowScreenRoute的类: 在这个类中可以导航到的屏幕定义如下:
sealed class OrderNowScreenRoute(val route:String){object Home :OrderNowScreenRoute(home)object Cart:OrderNowScreenRoute(cart)object ProductList:OrderNowScreenRoute(product_list)object ProductDetail:OrderNowScreenRoute(product_detail)
}
OrderNowNavHost 和 AppSoGraph
现在我们创建OrderNowNavHost类它将像这样表示应用程序的NavHost: Composable
fun OrderNowNavHost(appState:OrderNowState){NavHost(navController appState.navController,5,startDestination1){appSoGraph(appState)}
}fun NavGraphBuilder.appSoGraph(appState: OrderNowState) {} 从之前的代码片段中我们应该强调以下定义 • OrderNowNavHost 需要知道 APP 的状态。 • NavController 是从 APP 状态中托管和获取的。 • Navigation mapappSoGraph将基于 APP 的状态创建并且是在 OrderNowNavHost 内定义的扩展。 为了继续完成 OrderNow 中导航的实现我们必须添加一个描述如下的辅助类。 NavigationBarSection NavigationBarSection 是一个辅助类代表应用程序底部菜单中组成筛选组的部分。 请记住我们可以从选项菜单或其他 UI 组件如链接、按钮或内部重定向中的操作开始导航。 在下一节中我们将对内部重定向从按钮、链接等进行更改现在让我们专注于从 BottomBar 导航。 我们看到NavigationBarSection帮助器类将如何只对Home和Cart屏幕进行分组这是我们希望从BottomBar菜单启用的选项。这个类将像这样放置在导航目录中: 它的实现是这样的:
sealed class OrderNowScreenRoute(val route:String){object Home :OrderNowScreenRoute(home)object Cart:OrderNowScreenRoute(cart)object ProductList:OrderNowScreenRoute(product_list)object ProductDetail:OrderNowScreenRoute(product_detail)
}sealed class NavigationBarSection(val title: String, val icon: ImageVector, val route:String){companion object{val sections listOf(OrderNowScreenRoute.Home,OrderNowScreenRoute.Cart)}object Home:NavigationBarSection(title Home , icon Icons.Default.Home, route OrderNowScreenRoute.Home.route)object Cart:NavigationBarSection(title Cart, icon Icons.Default.ShoppingCart, route OrderNowScreenRoute.Cart.route)
}将helper类添加到项目中后我们继续更新OrderNowNavHost类如下所示:
Composable
fun OrderNowNavHost(appState: OrderNowState, paddingValues: PaddingValues) {NavHost(navController appState.navController,startDestination NavigationBarSection.Home.route,modifier Modifier.padding(paddingValues)) {appSoGraph(appState)}
}fun NavGraphBuilder.appSoGraph(appState: OrderNowState) {composable(NavigationBarSection.Home.route) {// HomeScreen()}composable(NavigationBarSection.Cart.route) {// CartScreen()}composable(OrderNowScreenRoute.ProductList.route){//ProductListScreen()}composable(OrderNowScreenRoute.ProductDetail.route){//ProductDetailScreen()}}
appSoGraph函数的实现是NavGraphBuilder的扩展在那里我们为App的每个屏幕指定导航地图。另外通过startDestination参数指定将首先呈现的默认屏幕即Home屏幕。采用更改的下一步是更新名为 OrderNowBottomBar 的类如下所示
Composable
fun OrderNowBottomBar(navController: NavHostController) {val navBackStackEntry by navController.currentBackStackEntryAsState()val currentDestination navBackStackEntry?.destinationBottomNavigation(backgroundColor MaterialTheme.colors.background,contentColor contentColorFor(MaterialTheme.colors.background),elevation 10.dp) {NavigationBarSection.sections.forEach { section -val selected currentDestination?.hierarchy?.any {it.route section.route} trueBottomNavigationItem(icon {Icon(imageVector ImageVector.vectorResource(R.drawable.ic_launcher_foreground),contentDescription stringResource(id R.string.app_name))},label { Text(text stringResource(id R.string.app_name)) },selected selected,unselectedContentColor Color.Gray,selectedContentColor Color.Red,onClick {navController.navigate(section.route) {popUpTo(navController.graph.findStartDestination().id) {saveState true}launchSingleTop truerestoreState true}})}}
}对于添加到 NavigationBarSection 中的每个项目BottomBar 中都会显示一个选项。OrderNowBottomBar 的这个实现比之前的架构主要结构中的实现更清晰。
然后我们再次更新 OrderNowScreen 视图如下所示 Preview
Composable
fun OrderNowScreeen(){MyTestTheme(){Surface {val appState rememberAppState()Scaffold(scaffoldState appState.scaffoldState,topBar {OrderNowTopBar()},bottomBar {OrderNowBottomBar(appState.navController)}){contentPadding -OrderNowNavHost(appState,contentPadding)}}}
}现在 OrderNowBottomBar 将需要引用负责导航的 navController。
在Scaffold的内容部分添加了OrderNowNavHost的实例该实例接收APP的一般状态作为参数。Order Now with simple navigation 从其他UI元素进行导航 现在我们已经准备好从 BottomBar 选项导航的实现我们需要定义从其他 UI 元素例如按钮、链接、DeepLinks甚至根据应用程序的其他内部组件的请求以编程方式导航应用程序。我们要做的第一个更改是添加一个名为 OrderNowNavigationState 的结构它允许我们扩展应用程序的一般状态。 OrderNowNavigationState是APP通用状态的扩展即一组用于导航目的的OrderNowState状态的扩展。我们还将使用此结构来集中取决于应用程序状态的导航逻辑。 OrderNowNavigationState的实现如下: fun OrderNowState.popUp(){navController.popBackStack()
}fun OrderNowState.navigate(route:String){navController.navigate(route){launchSingleTop true}
}fun OrderNowState.navigateAndPopUp(route:String,popUp:String){navController.navigate(route){launchSingleTop truepopUpTo(popUp){inclusive true}}
}fun OrderNowState.navigateSaved(route:String,popUp:String){navController.navigate(route){launchSingleTop truerestoreState truepopUpTo(popUp){saveState true}}
}fun OrderNowState.clearAndNavigate(route:String){navController.navigate(route){launchSingleTop truepopUpTo(0){ inclusive true}}
}
对Home、ProductList和ProductDetail屏幕做了一些更改如下图所示: 以in - home视图为例导航动作通过Button执行方式如下: Composable
fun HomeScreen(goToProductList:()-Unit,modifier:ModifierModifier,viewModel2:HomeViewModel hiltViewModel()){Column(){Button(onClick goToProductList,){Text(text stringResource(id R.string.app_name))}}
}
代码的重要部分是“Go to — ProductList Screen”按钮的动作 onClick goToProductList 的定义其中通过设计原理章节中解释的状态提升技术我们将动作 goToProductList 委托给在 OrderNowNavHost 中定义的 appSoGraph 导航图如下
un NavGraphBuilder.appSoGraph1(appState:OrderNowState){val goToListFromHome:()-Unit {appState.navigateSaved(OrderNowScreenRoute.ProductList.route,OrderNowScreenRoute.Home.route)}composable(NavigationBarSection.Home.route){HomeScreen(goToProductList goToListFromHome)}
}
回想一下navigatesave函数是OrderNowNavigationState结构中定义的扩展的一部分。同样的实现应用于导航到其他ProductList和ProductDetail屏幕这样在OrderNowNavHost中的性能如下所示:
fun NavGraphBuilder.appSoGraph2(appState:OrderNowState){val homeRoute OrderNowScreenRoute.Home.routeval listRoute OrderNowScreenRoute.ProductList.routeval detailRoute OrderNowScreenRoute.ProductDetail.routeval goToListFromHome:()-Unit {appState.navigateSaved(listRoute,homeRoute)}val goToDetailFromList:()-Unit {appState.navigateSaved(detailRoute,listRoute)}val goBack:()-Unit {appState.popUp()}composable(NavigationBarSection.Home.route){HomeScreen(goToProductList goToListFromHome)}composable(NavigationBarSection.ProductList.route){ProductListScreen(goToProductDetail goToDetailFromList,goBack goBack)}composable(NavigationBarSection.ProductDetail.route){ProductDetailScreen(goBack goBack)}}
总结起来前面的代码段中配置了以下导航定义导航图
从主页Home screen导航到产品列表ProductList screen。从产品列表ProductList screen导航到产品详情ProductDetail screen。从产品详情ProductDetail screen导航回到上一个呈现的屏幕。从底部导航栏菜单导航到主页Home screen。从底部导航栏菜单导航到购物车Cart screen。
到此为止我们在 OrderNow 应用中已经实现了一个很好的基本导航。然而还有一些东西缺失。 您有什么想法可能是缺失的吗 我们需要在导航中包含数据或信息的传递。 由于在本章中设计了相关的实现因此很容易实现数据传递。我们将在最后“实现功能”中详细探讨。
总结
本章中我们完成了应用程序的主要部分的设计这些将是以后添加功能的基础。 我们知道导航是应用程序的重要组成部分必须从应用程序设计的开始就考虑它。 在本章中我们采用了谷歌的建议将状态纳入导航逻辑中。 同时读者可以注意到我们的策略中没有直接涉及 ViewModel 或 View这使得它在测试时更加灵活可以检查导航。