当前位置: 首页 > wzjs >正文

公司网站建设哪家正规网络运营课程培训班

公司网站建设哪家正规,网络运营课程培训班,南通网站制作建设,注重网站内容维护目录: 前言定义导航图(Navigation Graph)和路由(Route),用代码声明页面跳转逻辑 2.1 composeable页面卸载的时候,数据如何保存? 2.2 composeable挂载页面的时候,是覆盖&…

目录:

  1. 前言
  2. 定义导航图(Navigation Graph)和路由(Route),用代码声明页面跳转逻辑
    2.1 composeable页面卸载的时候,数据如何保存?
    2.2 composeable挂载页面的时候,是覆盖,还是替换呢?

一、前言

最近在学习compose,先是找文章来学习,然后看github上面的源码来学习,最后再找视频来学习,然后再上github的项目学习,接着在根据项目的源码,自己删除再重新写一遍。一波三折。

在学习的过程,我就有一个疑问,只有一个Activity,也没有看到Fragment呢,也没有看到更多的Fragment,我好奇,compose的生命周期是如何的,他的页面又是如何加载的,没看到onstart方法,或者页面停止的时候onstop方法。

接下来,我们来解答一下这些疑惑。


二、通过定义导航图(Navigation Graph)和路由(Route),用代码声明页面跳转逻辑

在 Jetpack Compose 中,不再推荐使用多个 Activity 或 Fragment 来实现页面跳转,而是采用 单一 Activity + 多 Composable 组件 + 导航库 的架构。这是 Compose 的核心理念:通过声明式 UI 和状态驱动的导航来简化开发。

  1. 单一 Activity:整个应用通常只有一个 Activity(MainActivity),所有页面切换通过 Composable 组件 的替换完成。
  2. 无 Fragment:Compose 完全抛弃 Fragment,直接通过 NavController 和 NavHost 管理页面栈。
  3. 声明式导航:通过定义导航图(Navigation Graph)和路由(Route),用代码声明页面跳转逻辑。

那么,为什么要使用这种方式呢?

  1. 传统多 Activity/Fragment 的痛点:
    1.1 每个 Activity 都有自己的生命周期,跨页面数据传递需要序列化(Parcelable/Serializable),容易导致内存泄漏或状态不一致
    1.2 每次跳转新 Activity 都会触发冷启动,导致界面卡顿。
  2. Compose 新架构的核心优势
    2.1 Composable 函数根据状态自动重组,无需手动更新视图。页面切换本质是 Composable 组件的重组,无需启动新 Activity 或 Fragment。
    2.2 通过 NavController 管理全局导航栈,跳转逻辑集中且类型安全。

接下来,我们就看看导航是如何使用的(需要有一定基础~~)。


2.1 代码例子

1、导航代码

fun AppScaffold() {val navCtrl = rememberNavController() // 获取导航控制器val navBackStackEntry by navCtrl.currentBackStackEntryAsState() // 监听导航栈变化 从而确定当前选中的底部导航项。这样可以确保底部导航栏的状态与当前显示的路由一致。val currentDestination = navBackStackEntry?.destination // 当前路由目标//接下来我要构建底部一个导航栏,所以需要使用到ScaffoldScaffold(modifier = Modifier.statusBarsPadding().navigationBarsPadding(),//底部的导航栏内容,会放到NavHost里面。bottomBar = {when (currentDestination?.route) {RouteName.HOME-> {BottomNavBarView(navCtrl = navCtrl)}RouteName.CATEGORY-> {BottomNavBarView(navCtrl = navCtrl)}RouteName.COLLECTION-> {BottomNavBarView(navCtrl = navCtrl)}RouteName.PROFILE-> {BottomNavBarView(navCtrl = navCtrl)}}},content = {// 定义需要保持状态的页面索引(防止页面切换时重置)var homeIndex = remember { 0 }var categoryIndex = remember { 0 }// 导航宿主容器NavHost(modifier = Modifier.background(MaterialTheme.colors.background),navController = navCtrl,startDestination = RouteName.HOME // 初始路由) {// 首页路由composable(route = RouteName.HOME) {HomePage(navCtrl)}// 分类页路由composable(route = RouteName.CATEGORY) {CategoryPage(navCtrl)}// 收藏页路由composable(route = RouteName.COLLECTION) {CollectPage(navCtrl)}// 个人中心页路由composable(route = RouteName.PROFILE) {ProfilePage(navCtrl)}}})
}

2、点击切换

@Composable
fun BottomNavBarView(navCtrl: NavHostController) {//导航的标题,图片,路径val bottomNavList = listOf(BottomNavRoute.Home,BottomNavRoute.Category,BottomNavRoute.Collection,BottomNavRoute.Profile)//底部导航栏ui。BottomNavigation {val navBackStackEntry by navCtrl.currentBackStackEntryAsState() // 监听导航栈变化 从而确定当前选中的底部导航项。这样可以确保底部导航栏的状态与当前显示的路由一致。val currentDestination = navBackStackEntry?.destination// 当前路由目标bottomNavList.forEach { screen ->BottomNavigationItem(modifier = Modifier.background(AppTheme.colors.themeUi),icon = {Icon(imageVector = screen.icon,contentDescription = null)},label = { Text(text = stringResource(screen.stringId)) },//判断当前页面是否在某个导航图中selected = currentDestination?.hierarchy?.any { it.route == screen.routeName } == true,//那个被选择,那个就高亮。onClick = {//如果点击相同的,那么就不管if (currentDestination?.route == screen.routeName) {return@BottomNavigationItem}//跳转navCtrl.navigate(screen.routeName)})}}
}

3、HomePage :一个背景,其他页面也都是,用来测试,就写的简单一些~

@Composable
fun HomePage(navCtrl: NavHostController,
) {Box(modifier =Modifier.fillMaxSize().background(Color.Red))
}

在这里插入图片描述
这里,还有一个疑问,那么他重组,其他页面内容又是如何保存的呢?还是说直接就销毁了呢?比如从首页切换到分类,那么是覆盖,还是什么呢?


2.2 挂载和卸载

Composable 的挂载/卸载:当 Composable 进入/退出组合(Composition)时,可以视为类似 onStart/onStop 的时机。可以通过

1、挂载(进入组合)

当 Composable ​首次被调用 或 ​在重组中被重新需要 时,会挂载到组合中。

初始化状态:通过 remember 或 mutableStateOf 创建的状态会被初始化。
​执行副作用:如 LaunchedEffect、DisposableEffect 的首次运行。
​构建 UI 树:将 Composable 添加到 Compose 的 UI 树中。

示例


@Composable
fun MyComponent() {// 挂载时初始化状态val count = remember { mutableStateOf(0) }// 挂载时启动副作用LaunchedEffect(Unit) {delay(1000)println("Component mounted!")}Text("Count: ${count.value}")
}
2、卸载(退出组合)

当 Composable ​在重组过程中不再被调用 时,会从组合中卸载。

常见场景:

条件语句跳过:因 if/when 条件不满足而不再执行。
​导航离开页面:通过 NavController 跳转到其他页面。
​父组件卸载:父 Composable 被卸载导致子组件连带卸载。

行为:
​清理副作用:触发 DisposableEffect 的 onDispose 或取消 LaunchedEffect 的协程。
​释放资源:如取消网络请求、关闭数据库连接。
​从 UI 树移除:Composable 的 UI 节点被销毁。

示例


@Composable
fun ParentComponent(showChild: Boolean) {if (showChild) {ChildComponent() // 挂载}// 当 showChild 变为 false 时,ChildComponent 卸载,因为条件不满足了,这里要好好理解。因为ChildComponent方法不被调用了,就会卸载掉。
}@Composable
fun ChildComponent() {// 副作用:挂载时启动,卸载时清理DisposableEffect(Unit) {val resource = allocateResource()onDispose {releaseResource(resource) // 卸载时执行清理}}Text("Child Component")
}

现在我们可以回答一个问题,比如从首页切换到分类,那么是覆盖,还是什么呢?不是覆盖,是重新绘制,消失就会被卸载掉,不会留着,绘制变更的内容。

那么页面数据呢?也会初始化,重新获取数据?看你使用的是什么样的

一、Composable 卸载后的状态

  1. ​状态是否销毁?

    ​普通状态(remember)​:
    使用 remember 保存的状态 ​会被销毁。当 Composable 卸载后,其内部状态会被释放,下次挂载时会重新初始化。

    
    @Composable
    fun Counter() {val count = remember { mutableStateOf(0) } // 卸载时销毁Button(onClick = { count.value++ }) {Text("Count: ${count.value}")}
    }
    

    ​可保存状态(rememberSaveable)​:
    使用 rememberSaveable 的状态会在 ​配置变更(如屏幕旋转)时保留,但 ​Composable 完全卸载后依然会被销毁。

val count = rememberSaveable { mutableStateOf(0) } // 配置变更保留,卸载销毁
  1. ​副作用是否清理?

    LaunchedEffect/DisposableEffect
    卸载时会自动取消协程或触发 onDispose 清理资源。

    DisposableEffect(Unit) {// 挂载时执行onDispose { // 卸载时清理 }}
    

二、重新挂载时的行为

当 Composable ​再次被调用进入组合 时(例如条件语句重新满足、导航返回页面等),会触发 ​重新挂载,此时:

  1. ​重新执行整个函数体

Composable 函数会从头到尾重新执行,包括:

所有 remember 的初始化
所有副作用的启动(如 LaunchedEffect)
  1. ​状态重置

除非使用 ​状态提升 或 ​持久化存储,否则状态会被重置:

// 示例:重新挂载时状态重置
@Composable
fun DynamicComponent(visible: Boolean) {if (visible) {val count = remember { mutableStateOf(0) } // 每次挂载都从 0 开始Button(onClick = { count.value++ }) {Text("Count: ${count.value}")}}
}

那么怎么办呢?使用viewmodel,大家应该都知道viewmodel的生命周期。其生命周期与 Activity/Fragment 或导航图绑定。通过 ViewModel 保存状态。


@Composable
fun PersistentCounter(viewModel: CounterViewModel = viewModel()) {Button(onClick = { viewModel.increment() }) {Text("Count: ${viewModel.count.value}")}
}class CounterViewModel : ViewModel() {val count = mutableStateOf(0)fun increment() { count.value++ }
}

比如说,我们发起一起请求,请求到的数据放到viewModel中,那么重新挂载的时候,直接把数据拿出来就可以,不需要重新执行请求

http://www.dtcms.com/wzjs/131076.html

相关文章:

  • 旅游网站设计论文摘要兰州网络推广关键词优化
  • ftp上传网站教程西安百度竞价代运营
  • 网站开发做账微信上怎么做广告推广
  • 房产网站电商怎么做营销网页
  • 记事本里做网站 怎么把字体免费建自己的网站
  • 如何做像京东淘宝那样的网站5000元网站seo推广
  • wordpress定时任务原理seo导航站
  • 通用网站建设需求分析种子搜索神器在线搜
  • 怎么做hello官方网站下载百度软件
  • 网站伪静态文件seo零基础教学视频
  • 医院网站建设投标书今日足球赛事分析推荐
  • 做网站大概什么价位危机公关处理方案
  • 简单的手机网站模板下载安装网页设计html代码大全
  • 有啥创意可以做商务网站的网站建设公司哪家好?该如何选择
  • 在线app网站优化软件哪个好
  • 永春建设局网站万网的app叫什么
  • 做国际网站有哪些seo排名计费系统
  • 室内效果图代做网站如何进行市场推广
  • 注册网站账号违法吗企业网站推广技巧
  • 电商网站设计工作内容关键词seo排名优化软件
  • 网站推广的含义雷神代刷网站推广
  • wordpress office插件开发qq群排名优化软件官网
  • 山东德州做网站上海百度推广平台
  • 网站开发毕业设计摘要范文郑州网站制作推广公司
  • 中国中建设计网站公司员工培训内容有哪些
  • 全球创新设计廊坊优化外包
  • 烟台网站设计制作公司电话专门做推广的公司
  • 网站整站下载器 全站克隆页面图片视频下载 仿站专用源码工具软件北京网站制作设计
  • 公司网站上的员工风采怎么做宁波网站推广找哪家
  • 有设计师做的装修效果图的网站友情链接seo