Jetpack compose 康奈尔笔记

快速上手

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

布局

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

隐式传参 CompositionLocal

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

拿出中等透明度这个值. CompositionLocalProvider中的所有元素,都会使用相同的透明度.
在这里插入图片描述

状态

条目内容
无状态组件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

TodoList的案例

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

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

条目内容
简介显示传参和隐式传参在这里插入图片描述在这里插入图片描述在这里插入图片描述
显示传参 1. 繁琐 2. 隔离较好
隐式传参 1. 方便 2. 一改全改(解决思路:提供provider,修改全局变量,并在函数末尾将数值改回来)
在这里插入图片描述
对于广泛使用的常用数据这样传参很麻烦.Compose 提供了CompositionLocal来隐式传递参数.创建以树为作用域的具名对象,让数据流经界面树.
在这里插入图片描述
MaterialTheme是一个单例.
主题在这里插入图片描述在这里插入图片描述
这个函数修改的是LocalContentAlpha.current,修改为ContentAlpha.medium.
FruitText(理解current,当前上下文)在这里插入图片描述
为了访问strings.xml,需要resource,访问resource需要上下文
在这里插入图片描述
创建自己的CompositionLocalElevation(海拔,海拔越高,阴影越大)在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
提供一些默认值
在这里插入图片描述
在这里插入图片描述
动态创建和静态创建的区别
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
定义主题参考创建项目时自动生成的主题
使用颜色在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述ContentColor为文本颜色在这里插入图片描述在这里插入图片描述在这里插入图片描述
处理文本Button的默认样式在这里插入图片描述在这里插入图片描述"这里的当前,就是指最近的祖先的值."
在这里插入图片描述在这里插入图片描述
一行文字使用不同的样式.
在这里插入图片描述
处理形状举例:Button的形状:大中小; 有些组件会根据主题修改适应上下文,默认情况下TextFiled使用小型形状主题,但它对底角应用零边角大小(就是直角).
在这里插入图片描述在这里插入图片描述

动画和手势

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

手势

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

和传统view集成

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

导航

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

附带效应(副作用)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李来群

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值