Jetpack compose 康奈尔笔记

快速上手

条目 内容
是什么 原生Android界面构建工具包
优势 -更少的代码
-直观(状态变化,自动更新界面)
-可以预览
-Material design
什么是可组合函数 -用函数描述外观和数据依赖
-不关注构建过程
预览 @Preview 函数不能带参数
布局 -Row水平排列
-Column垂直排列
Jetpack compose 康奈尔笔记_第1张图片
修饰器 大小,外观,高级互动(例如使元素可以点击)
深色浅色主题切换
Jetpack compose 康奈尔笔记_第2张图片
Material design 颜色,排版,形状
Jetpack compose 康奈尔笔记_第3张图片
Jetpack compose 康奈尔笔记_第4张图片
Jetpack compose 康奈尔笔记_第5张图片
列表和状态,动画 Jetpack compose 康奈尔笔记_第6张图片Jetpack compose 康奈尔笔记_第7张图片https://developer.android.google.cn/jetpack/compose/themes/material?hl=zh-cn 颜色,字体Style(什么字体,多大)和形状.
状态在这里插入图片描述Jetpack compose 康奈尔笔记_第8张图片Jetpack compose 康奈尔笔记_第9张图片在这里插入图片描述
动画
在这里插入图片描述Jetpack compose 康奈尔笔记_第10张图片Jetpack compose 康奈尔笔记_第11张图片
深入详解Compose优化UI构建
-Compose解决的问题
-Compose函数剖析
-声明式UI
-组合VS继承
-重组
解决的问题: 减少耦合增加内聚 .将界面和数据用相同的语言来编写,一些隐式的依赖就会更加明显.Jetpack compose 康奈尔笔记_第12张图片Jetpack compose 康奈尔笔记_第13张图片
命令式需要自己更新UI, 声明式是数据绑定,当数据发生变化,自动更新UI.
组合VS继承
重组,将界面发生变化时,只进行部分重绘Jetpack compose 康奈尔笔记_第14张图片Jetpack compose 康奈尔笔记_第15张图片
状态改变时,自动重绘. 没有回调函数了,也不需要订阅了.
总结:

布局

条目 内容
标准布局组件 Column(垂直)
Row(水平)
Box(层叠)
修饰符 类似CSS
大小,布局,行为,外观
添加信息,例如无障碍标签
处理用户输入
高级互动,例如可点击,可滚动,可拖动,或可缩放
Jetpack compose 康奈尔笔记_第16张图片
Jetpack compose 康奈尔笔记_第17张图片
点击时显示黑色背景波纹(clickable的作用)Jetpack compose 康奈尔笔记_第18张图片
clickable修饰组件内部,padding修饰组件外部.Jetpack compose 康奈尔笔记_第19张图片
Slots(卡槽) API TopAppBar
Scaffold 提供topAppBar,bottomAppBar,FloatingActionButton,Drawer的槽位
在这里插入图片描述Jetpack compose 康奈尔笔记_第20张图片Jetpack compose 康奈尔笔记_第21张图片Jetpack compose 康奈尔笔记_第22张图片
使用列表 Column Row LazyColumn lazyRow
Jetpack compose 康奈尔笔记_第23张图片
默认是不支持滚动的,需要支持滚动(状态变化才会重绘,也叫重组,没有状态是不能滑动的)Jetpack compose 康奈尔笔记_第24张图片Jetpack compose 康奈尔笔记_第25张图片
让jetpack compose支持从网络加载图片(需要添加网络访问权限) coil
Jetpack compose 康奈尔笔记_第26张图片
ScrollToTop ScrollToBottom
Jetpack compose 康奈尔笔记_第27张图片
自定义布局 自定义修饰符 案例:firstBaseline ToTop 文字底部到父元素的距离在这里插入图片描述Jetpack compose 康奈尔笔记_第28张图片Jetpack compose 康奈尔笔记_第29张图片Jetpack compose 康奈尔笔记_第30张图片在这里插入图片描述
Jetpack compose 康奈尔笔记_第31张图片
layout 修饰符来修改元素的测量和布局方式Jetpack compose 康奈尔笔记_第32张图片
MyOwnColumn (这个应该叫,自定义容器)Jetpack compose 康奈尔笔记_第33张图片
Jetpack compose 康奈尔笔记_第34张图片
Jetpack compose 康奈尔笔记_第35张图片
StaggeredGrid(交错网格-棋盘)
Jetpack compose 康奈尔笔记_第36张图片
Jetpack compose 康奈尔笔记_第37张图片
Jetpack compose 康奈尔笔记_第38张图片
约束布局 引用-createRefsor createRefFor parent是一个现有的引用
约束条件 constrainAs linkto
Jetpack compose 康奈尔笔记_第39张图片
Jetpack compose 康奈尔笔记_第40张图片
Jetpack compose 康奈尔笔记_第41张图片
Jetpack compose 康奈尔笔记_第42张图片
Jetpack compose 康奈尔笔记_第43张图片
Jetpack compose 康奈尔笔记_第44张图片
解耦API
- 将布局和约束分离,根据屏幕修改约束条件.两个约束集之间可以添加动画效果.
Jetpack compose 康奈尔笔记_第45张图片
Jetpack compose 康奈尔笔记_第46张图片
BoxWithConstraints 可以获取父容器的大小,比如例子中的maxWidth 和 maxHeight.
Intrinsics(内部函数) Compose只测量子元素一次,测试两次会引发运行时异常.但是,有时在测量子元素之前,我们需要一些有关元素的信息.
Intrinsic允许在实际测量之前查询子项
(min,max)intrinsicWidth:鉴于此高度,您可以正确绘制内容的最小和最大宽度是多少
(min,max)intrinsicHeight:鉴于此高度,您可以正确绘制内容的最小和最大高度是多少
在这里插入图片描述
Jetpack compose 康奈尔笔记_第47张图片
Jetpack compose 康奈尔笔记_第48张图片

隐式传参 CompositionLocal

A()
{
  var i =45
  B(i)
}

拿出中等透明度这个值. CompositionLocalProvider中的所有元素,都会使用相同的透明度.
Jetpack compose 康奈尔笔记_第49张图片

状态

条目 内容
无状态组件 Jetpack compose 康奈尔笔记_第50张图片
Jetpack compose 康奈尔笔记_第51张图片
Jetpack compose 康奈尔笔记_第52张图片
Jetpack compose 康奈尔笔记_第53张图片

Jetpack compose 康奈尔笔记_第54张图片Jetpack compose 康奈尔笔记_第55张图片
Jetpack compose 康奈尔笔记_第56张图片
非结构化状态 (传统view) Jetpack compose 康奈尔笔记_第57张图片
Jetpack compose 康奈尔笔记_第58张图片
缺点
- 测试: UI和代码混在一起,需要手动操作软件来测试,而不是通过函数调用测试
- 部分状态更新: 屏幕有很多事件时,可能忘记部分状态
- 部分UI更新: 每次状态改变后要手动更新UI,可能忘记更新某些控件的显示
- 代码复杂性: 代码难以阅读
单向数据流(传统view 的解决方式) 为了解决非结构化状态的问题,引入了ViewModel和LiveData.
将状态从Activity移动到了ViewModel,在Viewmodel中,状态用LiveData 表示.
LiveData是一种可观察的容器,在界面中使用observe方法,可以在状态变化时更新界面.
Jetpack compose 康奈尔笔记_第59张图片
LiveData的set方法是protected,所以name是只读的. 不能通过name修改_name;写操作必须通过指定的函数来做;这就是单向数据流
Jetpack compose 康奈尔笔记_第60张图片
Jetpack compose 康奈尔笔记_第61张图片
Jetpack compose 康奈尔笔记_第62张图片
事件向上流动,状态向下流动
- 分离状态和UI, 测试容易,直接调用onNameChanged函数就可以测试.
- 状态封装 ,状态只能在viewmodel中更新,随着UI增长,不容易引入部分状态更新问题.
- UI一致性,所有的状态更新都通过使用可观察状态持有者立即反映在UI中
Compose的状态管理 Jetpack compose 康奈尔笔记_第63张图片
Jetpack compose 康奈尔笔记_第64张图片
Jetpack compose 康奈尔笔记_第65张图片
在这里插入图片描述
把状态放到viewModel里面(放到父函数里面也行),这种操作叫做状态提升,将状态转移给调用Compose的调用方.而组合本身是无状态的.
compose函数有两个输入参数:1. 数据2. 对数据的操作函数.
重组和remember Jetpack compose 康奈尔笔记_第66张图片
每次添加新元素,现有的透明度也会跟着改变,以为发生了重组.所以需要引入remember.
系统会将由remember计算的值存储在组合树种,只有当remember的键发生变化时才会重新计算.
Jetpack compose 康奈尔笔记_第67张图片
Jetpack compose 康奈尔笔记_第68张图片
使用remember会是的该可组合项有状态;
调用方不需要控制状态,而且不需要管理状态时,"有状态"非常有用,但有内部状态的可组合项往往不易重复使用,更难测试
将由状态的可组合项改成无状态,一种简单的做法是使用状态提升.
MutableState 在这里插入图片描述
Jetpack compose 康奈尔笔记_第69张图片
Jetpack compose 康奈尔笔记_第70张图片
总结 * 先做了一个静态界面
* 状态
* 传统view的更新方法
   - 单向数据流(ViewModel和LiveData),单向数据流指的是事件向上流动和状态(数据)向下流动
  - 将状态管理放到ViewModel也叫状态提升(函数需要两个输入参数:value和onValueChange函数)
* Compose的remember
* MutableState 状态变化时重组
xx yy

TodoList的案例

条目 内容
弹出菜单-动画效果的实现 Jetpack compose 康奈尔笔记_第71张图片
配置软键盘 Jetpack compose 康奈尔笔记_第72张图片TextField(keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Done))//将Enter替换为完成按钮 ImeAction.Done;类似的还有ImeAction.Go
添加带动画阴影和内容动画 Jetpack compose 康奈尔笔记_第73张图片Jetpack compose 康奈尔笔记_第74张图片Jetpack compose 康奈尔笔记_第75张图片
编辑模式 Jetpack compose 康奈尔笔记_第76张图片Jetpack compose 康奈尔笔记_第77张图片
Jetpack compose 康奈尔笔记_第78张图片
保存和恢复状态 在重新创建Activity或者进程(被杀死)后,可以使用rememberSaveable恢复界面状态.
存储格式
* Bundle
* Parcelize 在这里插入图片描述Jetpack compose 康奈尔笔记_第79张图片Jetpack compose 康奈尔笔记_第80张图片
* mapSaver Jetpack compose 康奈尔笔记_第81张图片
* ListSaverJetpack compose 康奈尔笔记_第82张图片
总结

Run 标准函数

data class Person(var name: String, var age: Int)

val person = Person("John", 30)

val result = with(person) {
    name = "Jane"
    age = 28
    "New name: $name, new age: $age"
}.let { it }

在这个例子中,我们首先使用 with 函数在 person 对象的上下文中执行一段代码块。然后,我们将 with 的返回值传递给 let 函数。由于 let 函数返回其代码块的最后一个表达式,我们可以将其简化为 it。这样,我们就实现了类似 run 的功能。

CompositionLocal

条目 内容
简介 显示传参和隐式传参Jetpack compose 康奈尔笔记_第83张图片Jetpack compose 康奈尔笔记_第84张图片Jetpack compose 康奈尔笔记_第85张图片
显示传参 1. 繁琐 2. 隔离较好
隐式传参 1. 方便 2. 一改全改(解决思路:提供provider,修改全局变量,并在函数末尾将数值改回来)
Jetpack compose 康奈尔笔记_第86张图片
对于广泛使用的常用数据这样传参很麻烦.Compose 提供了CompositionLocal来隐式传递参数.创建以树为作用域的具名对象,让数据流经界面树.
Jetpack compose 康奈尔笔记_第87张图片
MaterialTheme是一个单例.
主题 在这里插入图片描述Jetpack compose 康奈尔笔记_第88张图片
这个函数修改的是LocalContentAlpha.current,修改为ContentAlpha.medium.
FruitText(理解current,当前上下文) Jetpack compose 康奈尔笔记_第89张图片
为了访问strings.xml,需要resource,访问resource需要上下文
Jetpack compose 康奈尔笔记_第90张图片
创建自己的CompositionLocal Elevation(海拔,海拔越高,阴影越大)Jetpack compose 康奈尔笔记_第91张图片
Jetpack compose 康奈尔笔记_第92张图片Jetpack compose 康奈尔笔记_第93张图片
在这里插入图片描述
Jetpack compose 康奈尔笔记_第94张图片
提供一些默认值
Jetpack compose 康奈尔笔记_第95张图片
Jetpack compose 康奈尔笔记_第96张图片
动态创建和静态创建的区别
compositionLocalOf ,如果修改提供的值,会引起读取该current值的组件重绘.
staticCompositionLocalOf ,更改绘导致提供CompositionLocal的整个content lambda被重组,而不仅仅是读取current值的组件.在这里插入图片描述

主题

条目 内容
是什么 1. 定了了很多Color: Primary,secondary,surface - Color.kt
2. 定义了文本样式:h1 h2 h3 Subtitle1 body1 Type.kt
3. 形状:定义了3种类别:小型,中型和大型;每个都可以定义要使用的形状,自定义样式(切割和圆角)和大小-Shape.kt
定义主题 参考创建项目时自动生成的主题
使用颜色 Jetpack compose 康奈尔笔记_第97张图片Jetpack compose 康奈尔笔记_第98张图片Jetpack compose 康奈尔笔记_第99张图片Jetpack compose 康奈尔笔记_第100张图片Jetpack compose 康奈尔笔记_第101张图片ContentColor为文本颜色Jetpack compose 康奈尔笔记_第102张图片Jetpack compose 康奈尔笔记_第103张图片Jetpack compose 康奈尔笔记_第104张图片
处理文本 Button的默认样式在这里插入图片描述Jetpack compose 康奈尔笔记_第105张图片"这里的当前,就是指最近的祖先的值."
Jetpack compose 康奈尔笔记_第106张图片Jetpack compose 康奈尔笔记_第107张图片
一行文字使用不同的样式.
Jetpack compose 康奈尔笔记_第108张图片
处理形状 举例:Button的形状:大中小; 有些组件会根据主题修改适应上下文,默认情况下TextFiled使用小型形状主题,但它对底角应用零边角大小(就是直角).
Jetpack compose 康奈尔笔记_第109张图片Jetpack compose 康奈尔笔记_第110张图片

动画和手势

条目 内容
简单值动画 将背景色从粉色改成绿色
直接改变背景色也可以,但是没有一个渐变的效果.
任务目标:给颜色改变添加渐变动画
在这里插入图片描述在这里插入图片描述
动画对于compose来说,就是一个不断变化的state,连续的重组. 内部是一个协程.
可以打animate看看Android studio 提示,看看还有哪些简单值动画.
可见性动画 可见<->不可见 之间的动画,举例:向上滚动式显示FloatingButton的文字. Jetpack compose 康奈尔笔记_第111张图片Jetpack compose 康奈尔笔记_第112张图片Jetpack compose 康奈尔笔记_第113张图片
另一个案例:消息从顶部滑入滑出
Jetpack compose 康奈尔笔记_第114张图片Jetpack compose 康奈尔笔记_第115张图片Jetpack compose 康奈尔笔记_第116张图片Jetpack compose 康奈尔笔记_第117张图片
内容大小动画 Jetpack compose 康奈尔笔记_第118张图片Jetpack compose 康奈尔笔记_第119张图片
多值动画 Jetpack compose 康奈尔笔记_第120张图片Jetpack compose 康奈尔笔记_第121张图片
实现弹性动画
Jetpack compose 康奈尔笔记_第122张图片
重复动画 Jetpack compose 康奈尔笔记_第123张图片
手势动画 实现滑动删除
第一步: 元素跟随手指滑动
第二步: 手指松开,元素由于惯性,继续滑动(根据滑动速度,手指滑动结束位置,最终决定是否要删除 ) Jetpack compose 康奈尔笔记_第124张图片Jetpack compose 康奈尔笔记_第125张图片
这是一个单行函数的写法,返回值类型为Modifier,这是一个扩展函数. composed是一个高阶函数,它的作用是组合多个 Modifier,并将它们应用于当前的 Modifier。
Jetpack compose 康奈尔笔记_第126张图片Jetpack compose 康奈尔笔记_第127张图片Jetpack compose 康奈尔笔记_第128张图片Jetpack compose 康奈尔笔记_第129张图片
处理元素滑动在这里插入图片描述Jetpack compose 康奈尔笔记_第130张图片Jetpack compose 康奈尔笔记_第131张图片Jetpack compose 康奈尔笔记_第132张图片Jetpack compose 康奈尔笔记_第133张图片
记录滑动速度
Jetpack compose 康奈尔笔记_第134张图片
记录滑动位置和时间,就可以计算得到速度.
Jetpack compose 康奈尔笔记_第135张图片
计算投掷速度
Jetpack compose 康奈尔笔记_第136张图片
由于摩擦力的原因,速度会逐渐衰减. 样条衰减 指数衰减Jetpack compose 康奈尔笔记_第137张图片
Jetpack compose 康奈尔笔记_第138张图片Jetpack compose 康奈尔笔记_第139张图片
设置滑动边界Jetpack compose 康奈尔笔记_第140张图片Jetpack compose 康奈尔笔记_第141张图片

手势

条目 内容
点击 clickableJetpack compose 康奈尔笔记_第142张图片在这里插入图片描述Jetpack compose 康奈尔笔记_第143张图片
滚动 Jetpack compose 康奈尔笔记_第144张图片Jetpack compose 康奈尔笔记_第145张图片
可滚动修饰符,scrol lable,可以检测滚动手势,但是不会偏移其内容,需要ScrollableController 才能正常运行.
Jetpack compose 康奈尔笔记_第146张图片
嵌套滚动,简单的嵌套滚动无需执行任何操作,启动滚动操作的手势会自动从子元素到父元素,子元素无法进一步滚动时,就会由父元素处理.Jetpack compose 康奈尔笔记_第147张图片Jetpack compose 康奈尔笔记_第148张图片
拖动 Jetpack compose 康奈尔笔记_第149张图片Jetpack compose 康奈尔笔记_第150张图片
滑动 滚动,拖动,滑动的区别
- 滚动,子元素大小超过父容器,只能一部分一部分的看,需要滚动.
- 拖动,给元素换坐标
- 滑动 获得推进力后,自动惯性跑一段.
Jetpack compose 康奈尔笔记_第151张图片
Jetpack compose 康奈尔笔记_第152张图片设置阈值,超过30%到下一个锚点.
在这里插入图片描述
多点触控 平移,缩放,旋转使用transformable修饰符,不会转换元素,只会检测手势. Jetpack compose 康奈尔笔记_第153张图片Jetpack compose 康奈尔笔记_第154张图片

和传统view集成

从XML 创建可组合 基于SunFlower项目(官方案例)
把植物详情改成Compose
Jetpack compose 康奈尔笔记_第155张图片
Jetpack compose 康奈尔笔记_第156张图片
我们使用了Databinding,所以可以在代码中直接通过ID访问元素.Jetpack compose 康奈尔笔记_第157张图片Jetpack compose 康奈尔笔记_第158张图片Jetpack compose 康奈尔笔记_第159张图片Jetpack compose 康奈尔笔记_第160张图片Jetpack compose 康奈尔笔记_第161张图片
dimen是在values文件夹中中定义的尺寸信息dimens.xml .获取单复数形式.在这里插入图片描述
在Compose中使用View Jetpack compose 康奈尔笔记_第162张图片Jetpack compose 康奈尔笔记_第163张图片
共用主题 使用传统view 的styles.xml Jetpack compose 康奈尔笔记_第164张图片

导航

条目 内容
集成导航 Overview ,Count,bills
传统的navigation - 一定要有一个navigation graph 导航图
- 要有一个NavHostFragment,指定navGraph
- 在navigation标签中指定startDestination
- 跳转通过findNavController.navigate
Compose 中的导航 这里写的是导航对应的目标页Jetpack compose 康奈尔笔记_第165张图片Jetpack compose 康奈尔笔记_第166张图片Jetpack compose 康奈尔笔记_第167张图片
设置导航部件Jetpack compose 康奈尔笔记_第168张图片
Jetpack compose 康奈尔笔记_第169张图片
支持跳转Jetpack compose 康奈尔笔记_第170张图片
参数传递 案例: 有多个账户,可以跳转到对应账户的页面
Jetpack compose 康奈尔笔记_第171张图片在这里插入图片描述
深层链接 在一个应用中打开第三方应用的指定页面 . Jetpack compose 康奈尔笔记_第172张图片Jetpack compose 康奈尔笔记_第173张图片在这里插入图片描述
Compose和View 的关系 传统view 调用的是SetContentView
compose 调用的是 SetContent,内部实际调用的还是SetContentView,传入参数为ComposeView,它集成自ViewGroup,内部东西怎么画的,dispatchDraw->Canvas.
jetpack compose的组件没有继承原来view 的那套体系,是通过画布配置的.

附带效应(副作用)

条目 内容
什么是附带效应 不是纯函数Jetpack compose 康奈尔笔记_第174张图片
组合函数也分为有副作用和无副作用的. 组合函数的特点:
- 执行顺序不定
- 可以并行执行
- 可能频繁的运行(状态改变,就会重组)
可组合函数是为了做声明式UI的,而我们会在UI做一些和界面描述不相关的操作.
处理副作用
* 虽然我们不希望函数执行中出现副作用,但显示是有一些逻辑只能作为副作用来处理,比如IO操作,计时,日志埋点等等,这些都是会对外界或者受到外界影响的逻辑,不能无限制的反复执行.所以compose需要能够合理的处理一些副作用:
* 副作用(比如下载)的执行时机是明确的,例如在Recomposition时等
* 副作用的执行次数的可控的,不应该随着函数反复执行.
* 副作用(比如组合函数从组件树移除时,如果该组件发了网络请求,应该取消接收)不会造成泄漏,例如对于注册要提供适当的时机取消注册.
危险的附带效应
* 写入共享对象的属性(写全局变量)
* 更新ViewModel中的可观察项(数据在多个组件中共享)
* 更改共享偏好设置 SharePerference
这些数据都是全局的,共享的
使用Effect API,可以用可预测的方式执行那些副作用.Effect API是和compose的生命周期关联的.何时执行?比如是compose加入到组件树的时候.什么时候释放资源? compose从组件树移除的时候.Jetpack compose 康奈尔笔记_第175张图片副作用也是根据这3个时间点来配合的.Jetpack compose 康奈尔笔记_第176张图片
LaunchedEffect & rememberCoroutineScope 如果要在可组合函数中进行耗时操作,就需要将耗时操作放到协程,协程需要在协程作用域中创建, 所以提供了LaunchedEffect用于创建协程.
副作用一般都是耗时操作,一般用协程来完成.
案例:带动画的消息提示窗(动画是耗时操作,一般在协程中执行)

LaunchedEffect 有一个key,key变化它的代码块就会重启.
如果上一个协程没做完,又需要重新执行代码块,就会自动把上个协程取消.
从组件树上移除,会取消协程.
rememberCoroutineScope LaunchedEffect 只能在可组合函数中使用,非组合函数可以使用rememberCoroutineScope,该函数可以在可组合函数外启动协程,且需要对这个协程存在作用域限制,以便在协程退出组合后自动取消.协程作用域取消后,它内部的所有协程也会取消.
rememberUpdatedState & DisposableEffect
SideEffect & produceState
derivedStateOf & snapshotflow

你可能感兴趣的:(笔记,android,动画)