Android 动画和过渡

Android 动画和过渡
(一) 动画
JetpackCompose提供了强大且可扩展的API,可以轻松地在应用程序的UI中实现各种动画。下面描述了如何使用这些API以及根据动画场景使用哪些API。
动画在现代移动应用程序中至关重要,以实现流畅和可理解的用户体验。许多Jetpack Compose Animation API都可以作为可组合的函数提供,就像布局和其他UI元素一样,并且它们由使用Kotlin协程暂停函数构建的低级API支持。本指南从在许多实际场景中有用的高级API开始,并继续解释为您提供进一步控制和定制的低级API。
下图可帮助决定用什么API来实现动画。
在这里插入图片描述

(1)如果要设置布局中内容更改的动画:
如果要设置外观和消失的动画:
使用“动画可见性”。
基于状态交换内容:
如果您正在交叉阅读内容:
使用交叉淡入淡出。
否则,请使用AnimatedContent。
否则,请使用Modifier.animateContentSize。
(2)如果动画基于状态:
如果动画发生在合成期间:
如果动画是无限的:
使用rememberInfiniteTransition。
如果同时设置多个值的动画:
使用updateTransition。
否则,请使用animate*AsState。
(3)如果要对动画时间进行精细控制:
使用动画,例如TargetBasedAnimation或DecayAnimation。
(4)如果动画是真实的唯一来源
使用可设置动画。
(5)否则,请使用AnimationState或animate。

1.高级动画API
Compose为许多应用程序中使用的几种常见动画模式提供了高级动画API。这些API是为符合Material Design Motion的最佳实践而定制的。

1.1动画可见性
AnimatedVisibility可组合设置其内容的外观和消失的动画。
代码示例:
var editable by remember { mutableStateOf(true) }
AnimatedVisibility(visible = editable) {
Text(text = “Edit”)
}
默认情况下,内容通过淡入和展开来显示,而通过淡出和收缩来消失。可以通过指定EnterTransition和ExitTransition来自定义转换。
代码示例:
var visible by remember { mutableStateOf(true) }
val density = LocalDensity.current
AnimatedVisibility(
visible = visible,
enter = slideInVertically {
// Slide in from 40 dp from the top.
with(density) { -40.dp.roundToPx() }
} + expandVertically(
// Expand from the top.
expandFrom = Alignment.Top
) + fadeIn(
// Fade in with the initial alpha of 0.3f.
initialAlpha = 0.3f
),
exit = slideOutVertically() + shrinkVertically() + fadeOut()
) {
Text(“Hello”, Modifier.fillMaxWidth().height(200.dp))
}

1.2为子对象设置进出动画
AnimateVisibility中的内容(直接或间接子对象)可以使用animateEnterExit修改器为每个子对象指定不同的动画行为。每个孩子的视觉效果是在AnimatedVisibility组合中指定的动画和孩子自己的进入和退出动画的组合。
AnimatedVisibility(
visible = visible,
enter = fadeIn(),
exit = fadeOut()
) {
// Fade in/out the background and the foreground.
Box(Modifier.fillMaxSize().background(Color.DarkGray)) {
Box(
Modifier
.align(Alignment.Center)
.animateEnterExit(
// Slide in/out the inner box.
enter = slideInVertically(),
exit = slideOutVertically()
)
.sizeIn(minWidth = 256.dp, minHeight = 64.dp)
.background(Color.Red)
) {
// Content of the notification…
}
}
}
1.3添加自定义动画
如果要在内置的进入和退出动画之外添加自定义动画效果,要通过AnimatedVisibility的content lambda中的Transition属性访问基础的Transition实例。添加到“过渡”实例的任何动画状态都将与AnimatedVisibility的进入和退出动画同时运行。AnimatedVisibility将一直等到“过渡”中的所有动画都完成后再删除其内容。对于独立于Transition创建的退出动画(例如使用animateAsState),AnimatedVisibility将无法解释它们,因此可能会在完成之前删除可组合的内容
AnimatedVisibility(
visible = visible,
enter = fadeIn(),
exit = fadeOut()
) { // this: AnimatedVisibilityScope
// Use AnimatedVisibilityScope#transition to add a custom animation
// to the AnimatedVisibility.
val background by transition.animateColor { state ->
i

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
最近接到一个任务,就是要修改原来用的官方support包TabLayout中的指示器线宽,改成固定值,当然网上有什么反射加padding什么的,可是治标不治本,切Tab过渡动画也加不了,什么?你告诉我github又xxx类似控件,可是为什么我要放弃google大神的源码呢,改改就能增加新功能了呢,为了达到目的,我就开始了下面一系列骚操作。0. 老规矩,先放效果图1. 骚操作之一:copy support包TabLayout 一份当做自己的自定义view本次骚操作是基于support '27.1.0'版本,从support '27.1.0'拷出文件到我的项目目录如下图,蓝色部分,四个文件,当然不是一帆风顺的,需要改点包名,取消掉一下注解警告,总之后面会放出源码 不同的版本可能需要拷贝出来的文件不一样哟,于support '27.1.0'版本需要拷出上图蓝色的4个文件2. 骚操作之二: fuck源代码,读懂之后开始改造首先指示器的线是画出来的,关键代码如下 (以下改动代码均为tabLayout类)   canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight,                             mIndicatorRight, getHeight(), mSelectedIndicatorPaint);OK, mIndicatorLeft是滚动或者点击切tab时候通过偏移量计算出来的,总之不重要,完成第一个目标。修改指示器线宽,思路呢,就是给mIndicatorLeft和mIndicatorRight做一个偏移量就行了, 看看我怎么改的吧其中2个成员变量是我在SlidingTabStrip类中新增的 private int mSelectedIndicatorWidth =  dpToPx(27);;         private int mMinTabWidth = Integer.MAX_VALUE;我这里偷懒一下就不做方法暴露了,直接写死了线宽为27dp了好了,已经完成修改线宽目标了。(扩展一下:这里你也可以修改draw方法,画个图,或者画个小圆圈什么的)接下来增加指示线滑动切tab的过渡动画很简单我就放代码吧,关键就是在onPageScrolled方法里面做点手脚总共改动就50来行吧,就达成效果了。是不是很简单。(简单才怪,总之做出来之后觉得确实蛮简单的) 这样改好处多多,为什么呢?xml基本不需要改变,tablayout名字改一下,代码也是导包改一下,替换官方tablayout的时候代码几乎不需要变化,是不是很爽?3. github下载,喜欢就给个star吧,如果对你有帮助的话https://github.com/zjw-swun/AppOrder4. 总结官方support包就是可以这么任性的拷贝出来,有时候一个拷出一个类根本没涉及到别的类,善假于物也。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值