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

我用Ai学Android Jetpack Compose之Composable函数

本篇,我们来学习Composable函数,答案来自 通义千问,这里出现了通用Ai的局限性,没法展示图片,没办法,去Android官网补充学习。希望通用Ai早日实现图文输出。

文章目录

  • 1.什么是Composable函数?
      • 1. **定义与特性**
        • A. **`@Composable`注解**
        • B. **不可变性**
        • C. **组合性**
      • 2. **工作原理**
        • A. **重组(Recomposition)**
        • B. **智能跳过**
        • C. **副作用处理**
      • 3. **常见Composable函数**
      • 4. **最佳实践**
      • 总结
  • 2.介绍一下Composable函数的生命周期
      • 1. **重组(Recomposition)**
        • A. **触发条件**
        • B. **过程**
      • 2. **首次绘制(Initial Composition)**
      • 3. **重组与重绘(Recomposition and Redrawing)**
      • 4. **副作用管理**
        • A. **`LaunchedEffect`**
        • B. **`DisposableEffect`**
        • C. **`SideEffect`**
      • 5. **组合退出(Composition Exit)**
      • 6. **最佳实践**
      • 总结
  • 3.说明

1.什么是Composable函数?

Composable函数是Jetpack Compose框架中的核心构建块,它们用于声明用户界面(UI)组件。与传统命令式UI不同,Composable函数采用声明式编程风格,允许开发者描述UI“应该是什么样子”,而不是详细说明如何一步步实现这个UI。下面将详细介绍Composable函数的概念、特点及其使用方式。

1. 定义与特性

A. @Composable注解
  • 每个Composable函数都必须用@Composable注解标记,表明该函数可以用来构建或组合UI。
  • 这个注解告诉编译器这是一个特殊的函数,它遵循特定的规则和约定,例如只能调用其他Composable函数等。
@Composable
fun Greeting(name: String) {
    Text(text = "Hello, $name!")
}
B. 不可变性
  • 理想情况下,Composable函数内部的状态是不可变的;任何状态变化都会触发新组件的创建,而非修改现有组件。
  • 使用remembermutableStateOf等API来管理可变状态,确保状态更新时能够正确触发UI重绘。
@Composable
fun Counter() {
    var count by remember { mutableStateOf(0) }
    Column {
        Text("Count: $count")
        Button(onClick = { count++ }) {
            Text("Increment")
        }
    }
}
C. 组合性
  • Composable函数可以相互嵌套和组合,形成复杂的UI结构。
  • 开发者可以通过简单的函数调用来构建层次化的UI组件树,而不需要手动管理视图层次结构。
@Composable
fun MyApp() {
    Column {
        Header()
        Content()
        Footer()
    }
}

@Composable
fun Header() {
    // Header UI
}

@Composable
fun Content() {
    // Main content UI
}

@Composable
fun Footer() {
    // Footer UI
}

2. 工作原理

A. 重组(Recomposition)
  • 当底层数据发生变化时,Compose会自动检测并重新执行相关的Composable函数,这个过程称为重组。
  • 只有受影响的部分会被重新计算,其余部分保持不变,从而提高了性能。
B. 智能跳过
  • 如果某个Composable函数的输入参数没有变化,Compose会跳过对该函数的重新执行,避免不必要的工作。
C. 副作用处理
  • Composable函数中可以包含副作用操作(如网络请求、文件I/O),但需要使用专门的API(如LaunchedEffect DisposableEffect)来确保这些操作在适当的时机执行,并且不会引起内存泄漏或其他问题。
@Composable
fun MyComponent(id: String) {
    val context = LocalContext.current
    LaunchedEffect(id) {
        // 执行带有id作为key的副作用操作
        // 如果id改变,此effect将会被取消并重新启动
        fetchData(context, id)
    }
}

3. 常见Composable函数

Jetpack Compose提供了丰富的内置Composable函数,用于快速构建各种UI元素:

  • 文本Text
  • 按钮Button
  • 输入框TextField
  • 布局容器RowColumnBox
  • 列表LazyColumnLazyRow
  • 卡片Card
  • 进度条CircularProgressIndicatorLinearProgressIndicator
  • 图标Icon

4. 最佳实践

  • 单一职责原则:每个Composable函数应专注于完成一个具体的任务,保持简洁明了。
  • 合理拆分逻辑:对于复杂的UI组件,考虑将其拆分为多个小的Composable函数,以提高代码的可读性和复用性。
  • 状态提升:尽量将状态提升到父组件中管理,使得子组件更加纯粹和易于测试。
  • 避免直接操作平台API:尽可能使用Compose提供的API来处理UI逻辑,减少对原生Android API的依赖。

总结

Composable函数是Jetpack Compose的核心概念之一,通过它们,开发者可以用声明式的方式轻松构建响应式的用户界面。理解Composable函数的工作原理及其最佳实践,有助于编写高效、易维护的代码。随着经验的积累,你会逐渐掌握如何充分利用这些工具来开发出令人惊艳的应用程序。

如果你有任何进一步的问题或需要更详细的解释,请随时提问!希望你能享受学习和使用Compose的过程。

2.介绍一下Composable函数的生命周期

Composable函数的生命周期是Jetpack Compose框架中一个重要的概念,它决定了UI组件如何响应状态变化、何时创建和销毁,以及如何高效地进行更新。理解这个生命周期对于编写高效的Compose代码至关重要。以下是关于Composable函数生命周期的详细介绍。

1. 重组(Recomposition)

A. 触发条件
  • 状态变化:当State对象中的值发生变化时,例如通过mutableStateOfLiveData等。
  • 依赖项改变:当使用LaunchedEffectDisposableEffect等副作用API时,如果其依赖项发生改变。
  • 手动请求:开发者可以调用composer.recompose()来强制触发重组(通常不推荐这样做)。
B. 过程
  • 检测变化:Compose会自动检测哪些状态或参数发生了变化。
  • 选择性执行:只有那些受变化影响的Composable函数会被重新执行,其余部分保持不变。
  • 优化性能:通过智能跳过不受影响的节点,减少了不必要的计算开销。

2. 首次绘制(Initial Composition)

这是指第一次构建UI树的过程,发生在应用启动或新组件被引入时。在此期间:

  • 所有必要的Composable函数都会被执行一次,以初始化UI结构。
  • 状态变量将被初始化,并且任何副作用操作(如网络请求)也会在这一步骤中启动。

3. 重组与重绘(Recomposition and Redrawing)

随着应用程序运行,可能会因为用户交互或其他原因导致状态变化。每当这种变化发生时:

  • Compose会触发重组过程,重新评估受影响的Composable函数。
  • 如果重组结果导致了UI的变化,则会触发重绘,更新屏幕上显示的内容。

4. 副作用管理

在某些情况下,你可能需要在特定的时间点执行一些副作用操作,比如发起网络请求、订阅事件源或处理动画。为了确保这些操作能够在正确的时机执行,并且不会引起内存泄漏等问题,Compose提供了几种特殊的API:

A. LaunchedEffect
  • 用于启动异步任务,例如在网络请求完成后更新UI。
  • 当依赖项(作为参数传递给LaunchedEffect)发生变化时,当前的任务会被取消,并重新启动新的任务。
@Composable
fun MyComponent(id: String) {
    val context = LocalContext.current
    LaunchedEffect(id) {
        // 发起网络请求
        fetchData(context, id)
    }
}
B. DisposableEffect
  • 用于注册一次性副作用,例如监听系统广播或添加回调。
  • 当依赖项发生变化或Composable函数不再处于组合中时,DisposableEffect会自动清理资源,防止内存泄漏。
@Composable
fun MyComponent() {
    var isRegistered by remember { mutableStateOf(false) }

    DisposableEffect(Unit) {
        if (!isRegistered) {
            registerSystemBroadcast()
            isRegistered = true

            onDispose {
                unregisterSystemBroadcast()
                isRegistered = false
            }
        }
    }
}
C. SideEffect
  • 用于执行不需要取消的简单副作用,如发送分析事件或记录日志。
@Composable
fun MyComponent() {
    SideEffect {
        Log.d("MyComponent", "Component has been recomposed.")
    }
}

5. 组合退出(Composition Exit)

当某个Composable函数从UI树中移除时(例如导航到另一个屏幕),会发生组合退出:

  • 所有的副作用操作(如LaunchedEffectDisposableEffect)会被自动清理。
  • 任何由该Composable函数持有的资源(如文件句柄、数据库连接等)都应该在这个时候释放。

6. 最佳实践

  • 最小化依赖:尽量减少Composable函数对全局状态的依赖,这样可以降低重组的频率。
  • 合理使用副作用API:根据具体的业务需求选择合适的副作用管理工具,确保副作用能够正确启动和清理。
  • 避免频繁重组:不要让每个状态变化都触发整个UI树的重组,而是只更新真正受影响的部分。

总结

Composable函数的生命周期围绕着“首次绘制”、“重组与重绘”以及“组合退出”这三个主要阶段展开。理解这些阶段及其内部机制有助于开发人员编写出更加高效、稳定的应用程序。此外,掌握如何正确使用副作用管理API也是确保良好用户体验的关键之一。

如果你有任何进一步的问题或需要更详细的解释,请随时提问!希望你能通过学习这些知识更好地掌握Jetpack Compose的精髓。

在这里插入图片描述
图 1. 组合中可组合项的生命周期。进入组合,执行 0 次或多次重组,然后退出组合。

3.说明

这里通义千问因为没法展示图片,我从Android官网找了下 Compose可组合项的生命周期,具体请查看网页,https://developer.android.google.cn/develop/ui/compose/lifecycle?hl=zh-cn

有些不理解,是吧,没关系,先了解一下,我们学了几个UI组件、跳转等知识后再回来学习这个


http://www.kler.cn/a/469337.html

相关文章:

  • Backend - C# EF Core 执行迁移 Migrate
  • 除了RAII和智能指针,还有哪些资源管理机制?
  • 神经网络第一课
  • 前后端环境配置java/vue/maven/node.js/mysql
  • LabVIEW瞬变电磁接收系统
  • 关系分类(RC)模型和关系抽取(RE)模型的区别
  • jenkins入门4 --window执行execute shell
  • 《量子比特:解锁人工智能并行计算加速的密钥》
  • dfs复习
  • 我用AI学Android Jetpack Compose之入门篇(1)
  • unity 播放 序列帧图片 动画
  • 【0379】Postgres内核 walreceiver (libpqwalreceiver API)分析
  • STM32完全学习——0V5640的JPEG模式采集
  • 如何利用 Jenkins 实现高效的邮件告警
  • 【计算机网络】课程 实验三 跨交换机实现 VLAN 间路由
  • 海思Linux(一)-Hi3516CV610的开发-ubuntu22_04环境创建
  • ref()使用举例【Vue3】
  • 安徽省地图arcgis数据美化后mxd文件shp格式下载后内容测评
  • mysql 报错 ERROR 1396 (HY000) Operation ALTER USER failed for root@localhost 解决方案
  • 在Linux中,如何查看和修改网络接口配置?
  • 软件测试——面试八股文(入门篇)
  • Python实现Scheme
  • 短视频矩阵源码开发/saas矩阵部署/api矩阵源码接口搭建
  • 使用深度学习来实现图像超分辨率 综述!
  • SqlSugar-文章目录
  • 服务器开发 的泛型(Generics)基础知识