Android: 动画自定义视图

Android: animated custom views

编辑 2:新的官方培训指南

开发者网站发布了UI相关内容的培训指南,这是索引:

如果您对其中任何一个感兴趣,这里是 link: https://developer.android.com/training/animation/


编辑:答案总结

我在 Android 中找到了 5 种制作动画的方法:

  1. 使用 Property AnimationView 属性 设置动画,以平滑地更改 rotationalpha , scale

  2. Frame Animations (AnimationDrawable): 快速改变图片,使其看起来像动画

  3. 向量设计图像(VectorDrawable) and animate them by editing them over time with AnimatedVectorDrawable

  4. 覆盖 onDraw() View 并通过在 canvas 中绘制来执行 Custom Drawing

  5. 使用Lottie, what reproduces animations from After Effects. Many animations available at LottieFiles.

但是,Android 也提供了一些 内置工具 ,例如 Scenes (that let you animate the transition among several layouts that share the Views), Shared elements(这让您产生传递 View 从一个 Activity 到另一个)等

API21 中添加了许多(如果不是全部)这些功能,单击此处 here 了解更多信息。

这里有一些有趣的 articles/blogs 动画:

最后,几个有趣的工具:


备注

我知道 Android 提供 scalealpharotatetranslation 等转换

例子

我想查看和比较 2 个示例。

1 - 自定义视图动画

例如,filling up a glass of water or drawing a path.

2 - 复杂视图动画

例如,Android 的 StackExchange 应用程序,登录屏幕动画(找不到视频,也没有检查 iOS 中的行为是否相同)。

问题

对于第一个例子,除了播放 GIF 或在短时间后手动更改图像,我想不出任何其他方式。

我不认为是这样,所以我想问一下,(1)你知道它是怎么做到的吗?

关于第二个例子,我只想到了一个想法,那就是设置一个 Path 并相应地移动 View,通过某种方式在 animate() 之后传递它。 (2)这可能吗?

除了上面提到的,(3)你还知道其他播放动画的技巧吗? (比如Scene transitions-在一个回答中提到-)

请分享!谢谢。

对于您的自定义视图,我建议您确定要为其设置动画的属性。

假设一个 ClockView,你在 OnDraw()

中设置了 paint、stroke 等之后

您可能想要 AsyncMethods/Runnables 在后台连续更新属性,从而产生逐帧动画,但实际上它不是 Fraame Animation,因为您只对视图的属性设置动画(向左转) 而不是整个框架

那里有几十个例子,只需一点谷歌搜索你就可以自己动手做

"Filling up a glass of water"动画是通过帧动画实现的直接候选,即一张一张的换图。 Here你可以看到一个不错的博客post描述了如何实现这种动画,它与你提到的"filling up a glass of water"基本相同:

另一个动画乍一看有点难

但是打开后"Show layout bounds"你可以看到那里没有魔法。基本上这只是一个平移动画,它将视图从一个位置平移到另一个位置。对于这个动画,困难的部分是实现寻找平移坐标的算法。在那之后动画只是通过 scene transition animation.

的几行代码
// assuming at this step all the views are at the initial position at x0, y0
TransitionManager.beginDelayedTransition(rootLayout);
// here set view coordinates to x1, y1 - the final position

Transitions 框架将为您完成剩下的工作。它会找到增量并为您执行动画。 Here you will find a nice article by Lucas Rocha.

do you know of other techniques to play animations?

在Android中你基本上有3种方法来实现动画:

  • 只需使用 view.startAnimation(...)
  • 即可为视图设置动画(缩放、alpha、旋转等)
  • 为 Drawable 设置动画(根据 Drawable,这可以是从动画矢量 drawable 到 frame animations 的任何东西)
  • 做自定义绘图和动画

显然,通过框架方法为视图设置动画比创建可绘制动画更容易,创建可绘制对象 (xml) 比自定义绘图更容易。

你提到了几天前刚出来的lottie。我们将看看它的表现如何,但它看起来很有前途。在引擎盖下,lottie 将解析 json 并使用 CanvasPath 进行一些自定义绘图(上面的第 3 个要点)
如果您可以使用 After Effects,这可能是 "easiest" 复杂动画(和跨平台!)的解决方案

大家也开始分享动画了,你可以在这里找到:
http://www.lottiefiles.com/


do you know how it's done?

(1) 视频看起来像是在自定义绘图。

  • 为水绘制并填充 Path,在顶部设置一些波浪动画,同时设置动画效果,并撒上一些白点。
  • 在它周围画一个玻璃的形状

这将涉及创建自定义视图 and/or 可绘制和覆盖 onDraw(Canvas) Path.lineTo 以及一些圆弧、立方体或四边形都可以解决问题...我是既不是设计师也不是矢量专家:)

我不认为这可以通过使用 animated vector drawables 轻松实现,但您可以通过应用路径变形动画来完成它。 (如果我没记错的话,动画矢量绘图只支持 21+)

(2) 视频仅对路径进行动画处理并摆动旗帜。这可以通过使用 AnimatedVectorDrawables 来实现(例如 this blog shows) and trimming the path beginnings/ends or again by doing custom drawing (and thus also supporting pre lolipop devices) by animating a Path, e.g. using PathMeasure.getSegment() 以连续动画路径。

(3) 动画,正如 已经指出的那样,是第一个提到的类型,只是动画(移动和缩放)视图。


Regarding the second example, only one idea came to my mind, and that's setting a Path and moving the View accordingly by passing it somehow after animate(). (2) Is this possible?

沿着路径移动视图显然是可能的,但是视图会移动,并且您仍然需要找到一种方法来绘制沿着它的路径,如上所述。

我想推荐一个我不久前写的库(最近发布),它允许您创建自定义视图并向它们添加动画。

你可以找到它here and a very simple demo here。 虽然我的演示坦率地说并没有那么令人印象深刻,但它们展示了库的强大功能,最重要的是如何使用它。

它适用于 Android 的 TimeInterpolator 及其任何子项(以及自定义项)。

动画完全使用 Canvas 绘制,唯一的区别是您可以获得一个动画值,该值根据 TimeInterpolator 作为时间的函数而变化。

您可以在视图中添加任意数量的动画,并独立控制它们。最重要的是,您不仅限于绘制非动画的东西。有一个专门的方法 (onDrawStatics)。