本文为稀土技术社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!
前言
前面用两篇文章介绍了 animateXxxAsState
动画的运用以及怎么自界说 animateXxxAsState
的动画 Api,而 animateXxxAsState
动画 Api 的一个非常重要参数 animationSpec
却一向没做过多介绍,咱们知道在传统的特点动画中是能够对动画运转的时长、推迟时间、速率曲线等进行装备,但是在前面介绍的 animateXxxAsState
的运用中并没有介绍到相关的装备,是 Compose 动画不支持相关装备吗?还是说仅仅animateXxxAsState
Api 不支持?当然不是,实践上animationSpec
这一参数便是专门对动画进行相应装备的。
从本篇开端就来一步步了解 Compose 的动画能进行哪些相关装备。
AnimationSpec
经过检查 animateXxxAsState
源码能够发现 animationSpec
参数是 AnimationSpec
类型的,而 AnimationSpec
是一个接口,源码如下:
interface AnimationSpec<T> {
fun <V : AnimationVector> vectorize(
converter: TwoWayConverter<T, V>
): VectorizedAnimationSpec<V>
}
那么是要咱们自己去完成这个接口去对动画进行装备么?当然能够,但这样太麻烦了,Compose 供给了一系列预置的完成类协助咱们对动画的常用装备项进行设置。来看一下 AnimationSpec
究竟有哪些预置的完成类,如图:
其间 FloatAnimationSpec
、FiniteAnimationSpec
、DurationBasedAnimationSpec
是接口,所以真实完成类有 8 个,而在这 8 个完成类中 FloatTweenSpec
、FloatSpringSpec
与 TweenSpec
、SpringSpec
作用基本是相同的,仅仅前者是只针对 Float 类型,而后者是针对一切类型,实践开发中运用后者即可,而前者一般是用于 Compose 动画底层完成辅助用的。
这样算下来 AnimationSpec
的真实完成类就只有 6 个了,别离是:
- KeyframesSpec:关键帧动画
- SnapSpec:快闪动画
- TweenSpec:补间动画
- RepeatableSpec:循环动画
- SpringSpec:弹簧动画
- InfiniteRepeatableSpec:无限循环动画
从这一篇开端咱们就针对这 6 个完成类进行一一探究,看看它们究竟能装备那些内容,能完成什么样的作用,本篇首先从最简略的 TweenSpec
开端。
TweenSpec
TweenSpec
补间动画是用于装备动画的时长、推迟时间以及运转速率曲线,看一下 TweenSpec
类的界说:
class TweenSpec<T>(
val durationMillis: Int = DefaultDurationMillis,
val delay: Int = 0,
val easing: Easing = FastOutSlowInEasing
) : DurationBasedAnimationSpec<T>
参数说明:
-
durationMillis:动画时长,单位毫秒,默以为
DefaultDurationMillis
为 300ms - delay: 动画推迟,单位毫秒,默以为 0,即推迟指定时间后履行动画
-
easing:动画运转速率曲线,默以为
FastOutSlowInEasing
下面来别离看看这三个参数具体怎么运用以及装备后的动画作用怎么。
动画时长
看过前面几篇文章细心的同学会发现前面介绍的一切 Compose 动画好像都不能设置动画时长,那么这儿咱们就能够经过 TweenSpec
来进行设置。
还是以之前的方块移动动画为例,经过给 animationSpec
参数设置 TweenSpec
来设置动画时长:
val startPadding by animateDpAsState(targetValue, animationSpec = TweenSpec(1000))
运转作用:
除了直接运用结构函数创立 TweenSpec
实例外,Compose 还供给了一个简洁的函数 tween
来进行创立,它的参数跟 TweenSpec
的结构参数彻底相同,运用如下:
val startPadding by animateDpAsState(targetValue, animationSpec = tween(1000))
实践上 tween
的完成便是调用的 TweenSpec
结构函数,源码如下:
fun <T> tween(
durationMillis: Int = DefaultDurationMillis,
delayMillis: Int = 0,
easing: Easing = FastOutSlowInEasing
): TweenSpec<T> = TweenSpec(durationMillis, delayMillis, easing)
动画推迟
经过设置 TweenSpec
的 delay
(运用 tween
函数时参数名为 delayMillis
)参数即可完成推迟启动动画 ,运用方式如下:
val startPadding by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, delayMillis = 1000))
运转作用:
动画速率曲线
前面两个参数都很好了解,这第三个参数 easing
究竟是什么意思呢?官方翻译为缓动,其实便是动画数值改动的速率曲线,类比特点动画便是插值器 Interpolator
, Compose 也供给了四种预置的动画速率曲线:
-
FastOutSlowInEasing:先加快后减速,对应特点动画插值器的
FastOutSlowInInterpolator
-
LinearOutSlowInEasing:先匀速后减速,对应特点动画插值器的
LinearOutSlowInInterpolator
-
FastOutLinearInEasing:先加快后匀速,对应特点动画插值器的
FastOutLinearInInterpolator
- LinearEasing:匀速运转
可能咱们对这四个曲线的命名不太好了解记不住,除了最终一个匀速外前面三个都是分为两段,如第一个的 FastOut、SlowIn,即动画开端的速率体现和动画完毕的速率体现,即加快开端然后减速完毕,为了协助咱们了解下面我画了一个简略的示意图:
经过这个示例图相信咱们对这四个曲线会有更好的了解,下面就来别离看一下这四个动画速率曲线的运用和作用。
FastOutSlowInEasing
动画加快开端,然后减速中止,运用代码如下:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = FastOutSlowInEasing))
作用:
这儿运用了一个辅助曲线协助咱们更好的了解装备 easing 后的动画作用与速率曲线的关系。
LinearOutSlowInEasing
动画匀速开端,然后减速中止,运用代码如下:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = LinearOutSlowInEasing))
作用:
FastOutLinearInEasing
动画加快开端,然后匀速中止,运用代码如下:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = FastOutLinearInEasing))
作用:
LinearEasing
动画从开端到完毕匀速运动,运用代码如下:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = LinearEasing))
作用:
自界说 Easing
除了上面介绍的 4 种 Compose 预置的动画速率曲线外咱们能否自界说其他曲线呢?答案是必定的。Easing 自身是一个接口类型,咱们只需自界说完成这个 Easing 接口即可自界说动画的速率曲线,Easing 界说如下:
fun interface Easing {
fun transform(fraction: Float): Float
}
其间 fraction
是动画的进展值,值为 0.0 ~ 1.0
之间,其间 0.0 为动画开端, 1.0 为动画完毕,返回的是转化后的 fraction 值,咱们能够经过修改 fraction 的转化规则来改动动画的速率曲线。
前面介绍的预置的 LinearEasing
便是最简略的自界说 Easing 完成,直接将 fraction 未做任何转化直接进行返回,源码如下:
val LinearEasing: Easing = Easing { fraction -> fraction }
假设咱们要自界说一个 Easing 类,完成当动画进展小于 0.3 或大于 0.7 时进行匀速运动,在 0.3 ~ 0.7 之间时停在动画的中心位置,代码应该这样写:
class CustomEasing : Easing {
override fun transform(fraction: Float): Float {
if (fraction < 0.3 || fraction > 0.7) {
return fraction
} else {
return 0.5f
}
}
}
运用:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = CustomEasing()))
看一下运转作用:
虽然作用怪怪的,但是确实是完成了自界说的作用
自界说贝塞尔曲线 Easing
Compose 供给了一个预置的 Easing 完成类 CubicBezierEasing
贝塞尔曲线的 Easing,而前面介绍的预置的 4 种曲线除了 LinearEasing 外其他三个都是经过 CubicBezierEasing
创立的,源码如下:
val FastOutSlowInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 0.2f, 1.0f)
val LinearOutSlowInEasing: Easing = CubicBezierEasing(0.0f, 0.0f, 0.2f, 1.0f)
val FastOutLinearInEasing: Easing = CubicBezierEasing(0.4f, 0.0f, 1.0f, 1.0f)
CubicBezierEasing
是三阶贝塞尔曲线,三阶贝塞尔曲线有 4 个点,起点为 (0,0) 完毕点位 (1,1) ,中心两个点则为 CubicBezierEasing
结构方法传入的数据,即 (x1,y1)、(x2,y2) 四个参数。
咱们能够经过 CubicBezierEasing
来创立自己想要的动画速率曲线,这儿引荐一个专门用来预览贝塞尔曲线速率动画的网站 cubic-bezier ,经过这个网站咱们能够设置自己想要的曲线并预览动画运转作用:
将上面的曲线经过 CubicBezierEasing
完成:
val CustomCubicBezierEasing: Easing = CubicBezierEasing(0.79f, -0.04f, 0.64f, 1.34f)
运用:
val offsetY by animateDpAsState(targetValue, animationSpec = tween(durationMillis = 1000, easing = CustomCubicBezierEasing))
运转作用:
在实践开发中 Compose 预置的四种 Easing 基本能满意大部分需求,即使需求自界说一般也是多用 CubicBezierEasing 来自界说动画速率曲线,而完成 Easing 接口进行自界说的情况则相对较少。
最终
本文对 Compose 动画的装备 AnimationSpec 进行了简略的介绍,并具体介绍了 TweenSpec
的运用,经过 TweenSpec
咱们能够对动画的时长、推迟时间以及动画速率曲线进行装备,而且可基于需求对动画的速率曲线进行自界说。下一篇将继续介绍 AnimationSpec 的其他装备实例,欢迎在下方关注专栏继续了解 Compose 动画相关内容。