Android样式的开发:View Animation篇

简介: 笔记

drawable汇总篇讲过两个动画,animation-list定义帧动画,animated-rotate定义旋转动画,这两个属于drawable动画。除了drawable动画,Android框架还提供了另外两种动画体系:视图动画(View Animation)和属性动画(Property Animation)。视图动画比较简单,只能应用于各种View,可以做一些位置、大小、旋转和透明度的简单转变。属性动画则是在android 3.0引入的动画体系,提供了更多特性和灵活性,也可以应用于任何对象,而不只是View。本篇先讲视图动画。

视图动画可以通过xml文件定义,xml文件放于res/anim/目录下,根元素可以为:, , , , 或者。其中,标签定义的是动画集,它可以包含多个其他标签,也可以嵌套标签。默认情况下,所有动画会同时播放;如果想按顺序播放,则需要指定startOffset属性;另外,还可以通过设置interpolator改变动画变化的速率,比如匀速、加速。


alpha


alpha可以实现透明度渐变的动画效果,也就是淡入淡出的效果,可通过设置下面三个属性来设置淡入或淡出效果:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:fromAlpha 动画开始时的透明度,0.0为全透明,1.0为不透明,默认为1.0
  • android:toAlpha 动画结束时的透明度,0.0为全透明,1.0为不透明,默认为1.0

当设置开始时透明度为0.0,结束时为1.0,就能实现淡入效果;相反,当设置开始时透明度为1.0,结束时为0.0,那就能实现淡出效果。示例代码如下:

<!-- res/anim/fade_in.xml -->
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromAlpha="0.0"
    android:toAlpha="1.0" />

将这动画效果添加到View上也只需要一行代码:

view.startAnimation(AnimationUtils.loadAnimation(this, R.anim.fade_in));

如果需要重用这个动画,也可以将其抽离出来。标签对应的动画类为AlphaAnimation,父类为Animation,以上代码将AlphaAnimation抽离后的代码可以如下:

AlphaAnimation fadeInAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.fade_in);
view.startAnimation(fadeInAnimation);


scale


scale可以实现缩放的动画效果,主要的属性如下:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:fromXScale 动画开始时X坐标上的缩放尺寸
  • android:toXScale 动画结束时X坐标上的缩放尺寸
  • android:fromYScale 动画开始时Y坐标上的缩放尺寸
  • android:toYScale 动画结束时Y坐标上的缩放尺寸
    PS以上四个属性,0.0表示缩放到没有,1.0表示正常无缩放,小于1.0表示收缩,大于1.0表示放大
  • android:pivotX 缩放时的固定不变的X坐标,一般用百分比表示,0%表示左边缘,100%表示右边缘
  • android:pivotY 缩放时的固定不变的Y坐标,一般用百分比表示,0%表示顶部边缘,100%表示底部边缘

示例代码如下:

<!-- res/anim/zoom_out.xml -->
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:pivotX="0%"
    android:pivotY="100%"
    android:toXScale="1.5"
    android:toYScale="1.5" />

标签对应的类为ScaleAnimation,父类也是Animation,添加到View上的用法和AlphaAnimation一样,代码如下:

ScaleAnimation zoomOutAnimation = (ScaleAnimation) AnimationUtils.loadAnimation(this, R.anim.zoom_out);
view.startAnimation(zoomOutAnimation);


translate


translate可以实现位置移动的动画效果,可以是垂直方向的移动,也可以是水平方向的移动。坐标的值可以有三种格式:从-100到100,以”%”结束,表示相对于View本身的百分比位置;如果以”%p”结束,表示相对于View的父View的百分比位置;如果没有任何后缀,表示相对于View本身具体的像素值。主要的属性如下:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:fromXDelta 起始位置的X坐标的偏移量
  • android:toXDelta 结束位置的X坐标的偏移量
  • android:fromYDelta 起始位置的Y坐标的偏移量
  • android:toYDelta 结束位置的Y坐标的偏移量

看示例吧,以下代码实现的是从左到右的移动效果,起始位置为相对于控件本身-100%的位置,即在控件左边,与控件本身宽度一致的位置;结束位置为相对于父控件100%的位置,即会移出父控件右边缘的位置。

<!-- res/anim/move_left_to_right.xml -->
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXDelta="-100%"
    android:fromYDelta="0"
    android:toXDelta="100%p"
    android:toYDelta="0" />

标签对应的类为TranslateAnimation,父类也是Animation,添加到View上的代码如下:

TranslateAnimation moveAnimation = (TranslateAnimation) AnimationUtils.loadAnimation(this, R.anim.move_left_to_right);
view.startAnimation(moveAnimation);


rotate


rotate可以实现旋转的动画效果,主要的属性如下:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:fromDegrees 旋转开始的角度
  • android:toDegrees 旋转结束的角度
  • android:pivotX 旋转中心点的X坐标,纯数字表示相对于View本身左边缘的像素偏移量;带”%”后缀时表示相对于View本身左边缘的百分比偏移量;带”%p”后缀时表示相对于父View左边缘的百分比偏移量
  • android:pivotY 旋转中心点的Y坐标,纯数字表示相对于View本身顶部边缘的像素偏移量;带”%”后缀时表示相对于View本身顶部边缘的百分比偏移量;带”%p”后缀时表示相对于父View顶部边缘的百分比偏移量

以下示例代码旋转角度从0到360,即旋转了一圈,旋转的中心点都设为了50%,即是View本身中点的位置。

<!-- res/anim/rotate_one.xml -->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%" />

标签对应的类为RotateAnimation,父类也是Animation,添加到View上的代码如下:

RotateAnimation rotateAnimation = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_one);
view.startAnimation(rotateAnimation);


set


set标签可以将多个动画组合起来,变成一个动画集。比如想将一张图片缩放的同时也做移动,这时候就要用标签组合缩放动画和移动动画了。示例代码如下:

<!-- res/anim/move_and_scale.xml -->
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000">
    <translate
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="200%"
        android:toYDelta="0" />
    <scale
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="0%"
        android:pivotY="100%"
        android:toXScale="1.5"
        android:toYScale="1.5" /></set>

以上代码实现的动画效果为向右移动的同时也同步放大。标签在视图动画中除了可以组合, , , 这四种标签,也可以嵌套其他标签。另外,标签可嵌套的标签元素并不只有这几个,后面谈到属性动画时会再讲其他的标签及用法。


通用属性


仔细观察不难发现,以上五个标签都有android:duration属性,这是一个通用的属性,而除了android:duration,还有其他的通用属性,接下来看看都有哪些通用属性以及相应的用法:

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:detachWallpaper 设置是否在壁纸上运行,只对设置了壁纸背景的窗口动画(window animation)有效。设为true,则动画只在窗口运行,壁纸背景保持不变
  • android:fillAfter 设置为true时,动画执行完后,View会停留在动画的最后一帧;默认为false;如果是动画集,需在标签中设置该属性才有效
  • android:fillBefore 设置为true时,动画执行完后,View回到动画执行前的状态,默认即为true
  • android:fillEnabled 设置为true时,android:fillBefore的值才有效,否则android:fillBefore会被忽略
  • android:repeatCount 设置动画重复执行的次数,默认为0,即不重复;可设为-1或infinite,表示无限重复
  • android:repeatMode 设置动画重复执行的模式,可设为以下两个值其中之一:
    restart 动画重复执行时从起点开始,默认为该值
    reverse 动画会反方向执行
  • android:startOffset 设置动画执行之前的等待时长,毫秒为单位;重复执行时,每次执行前同样也会等待一段时间
  • android:zAdjustment 表示被设置动画的内容在动画运行时在Z轴上的位置,取值为以下三个值之一:
    normal 默认值,保持内容在Z轴上的位置不变
    top 保持在Z周最上层
    bottom* 保持在Z轴最下层
  • android:interpolator 设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源,后面再详细讲解
    PS:标签还有个android:shareInterpolator属性,设置为true时则可将interpolator应用到所有子元素中


Interpolator


通过interpolator可以定义动画速率变化的方式,比如加速、减速、匀速等,每种interpolator都是 Interpolator 类的子类,Android系统已经实现了多种interpolator,对应也提供了公共的资源ID,如下表:

Interpolator class Resource ID Description
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator 在动画开始与结束时速率改变比较慢,在中间的时候加速
AccelerateInterpolator @android:anim/accelerate_interpolator 在动画开始时速率改变比较慢,然后开始加速
AnticipateInterpolator @android:anim/anticipate_interpolator 动画开始的时候向后然后往前抛
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator 动画开始的时候向后然后向前抛,会抛超过目标值后再返回到最后的值
BounceInterpolator @android:anim/bounce_interpolator 动画结束的时候会弹跳
CycleInterpolator @android:anim/bounce_interpolator 动画循环做周期运动,速率改变沿着正弦曲线
DecelerateInterpolator @android:anim/decelerate_interpolator 在动画开始时速率改变比较快,然后开始减速
LinearInterpolator @android:anim/decelerate_interpolator 动画匀速播放
OvershootInterpolator @android:anim/overshoot_interpolator 动画向前抛,会抛超过最后值,然后再返回

如果系统提供的以上Interpolator还不符合你的效果,也可以自定义。自定义的方式有两种,一种是通过继承 Interpolator 父类或其子类;另一种是通过自定义的xml文件,可以更改上表中Interpolator的属性。自定义的xml文件需存放于res/anim/目录下,根标签与上表相应的有九种如下:

  • 在动画开始与结束时速率改变比较慢,在中间的时候加速。没有可更改设置的属性,所以设置的效果和系统提供的一样
  • 在动画开始时速率改变比较慢,然后开始加速。有一个属性可以设置加速的速率
    android:factor* 浮点值,加速的速率,默认为1
  • 动画开始的时候向后然后往前抛。有一个属性设置向后拉的值
    android:tension* 浮点值,向后的拉力,默认为2,当设为0时,则不会有向后的动画了
  • 动画开始的时候向后然后向前抛,会抛超过目标值后再返回到最后的值。可设置两个属性
    android:tension 浮点值,向后的拉力,默认为2,当设为0时,则不会有向后的动画了
    android:extraTension 浮点值,拉力的倍数,默认为1.5(2*1.5),当设为0时,则不会有拉力了
  • 动画结束的时候会弹跳。没有可更改设置的属性
  • 动画循环做周期运动,速率改变沿着正弦曲线。有一个属性设置循环次数
    android:cycles* 整数值,循环的次数,默认为1
  • 在动画开始时速率改变比较快,然后开始减速。有一个属性设置减速的速率
    android:factor* 浮点值,减速的速率,默认为1
  • 动画匀速播放。没有可更改设置的属性
  • 动画向前抛,会抛超过最后值,然后再返回。有一个属性
    android:tension* 浮点值,超出终点后的拉力,默认为2

具体用法,就举个示例吧,先定义个interpolator的xml文件,代码如下:

<!-- res/anim/my_interpolator.xml -->
<?xml version="1.0" encoding="utf-8"?>
<anticipateOvershootInterpolator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:tension="3"
    android:extraTension="2" />

接着,将其设置到要应用的动画的android:interpolator属性即可,代码如下:

<!-- res/anim/rotate_one.xml -->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:toDegrees="360"
    android:pivotX="50%"
    android:pivotY="50%"
    android:interpolator="@anim/my_interpolator" />


写在最后


视图动画的应用主要就这些了,比较简单,当然也有其局限性。比如只能应用于View,也只能做渐变、缩放、旋转和移动,以及这些动画的组合。下一篇再详细讲解属性动画,属性动画可以轻而易举的做到许多视图动画做不到的事,比如说图片的翻转。

相关文章
|
5月前
|
Android开发 UED 计算机视觉
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
本文介绍了一款受游戏“金铲铲之战”启发的Android自定义View——线条等待动画的实现过程。通过将布局分为10份,利用`onSizeChanged`测量最小长度,并借助画笔绘制动态线条,实现渐变伸缩效果。动画逻辑通过四个变量控制线条的增长与回退,最终形成流畅的等待动画。代码中详细展示了画笔初始化、线条绘制及动画更新的核心步骤,并提供完整源码供参考。此动画适用于加载场景,提升用户体验。
442 5
Android自定义view之线条等待动画(灵感来源:金铲铲之战)
|
10天前
|
开发工具 Android开发
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
154 11
X Android SDK file not found: adb.安卓开发常见问题-Android SDK 缺少 `adb`(Android Debug Bridge)-优雅草卓伊凡
|
14天前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
46 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
20天前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
79 6
|
5月前
|
Android开发
Android自定义view之利用PathEffect实现动态效果
本文介绍如何在Android自定义View中利用`PathEffect`实现动态效果。通过改变偏移量,结合`PathEffect`的子类(如`CornerPathEffect`、`DashPathEffect`、`PathDashPathEffect`等)实现路径绘制的动态变化。文章详细解析了各子类的功能与参数,并通过案例代码展示了如何使用`ComposePathEffect`组合效果,以及通过修改偏移量实现动画。最终效果为一个菱形图案沿路径运动,源码附于文末供参考。
|
5月前
|
Android开发 开发者
Android自定义view之利用drawArc方法实现动态效果
本文介绍了如何通过Android自定义View实现动态效果,重点使用`drawArc`方法完成圆弧动画。首先通过`onSizeChanged`进行测量,初始化画笔属性,设置圆弧相关参数。核心思路是不断改变圆弧扫过角度`sweepAngle`,并调用`invalidate()`刷新View以实现动态旋转效果。最后附上完整代码与效果图,帮助开发者快速理解并实践这一动画实现方式。
139 0
|
5月前
|
XML Java Android开发
Android自定义view之网易云推荐歌单界面
本文详细介绍了如何通过自定义View实现网易云音乐推荐歌单界面的效果。首先,作者自定义了一个圆角图片控件`MellowImageView`,用于绘制圆角矩形图片。接着,通过将布局放入`HorizontalScrollView`中,实现了左右滑动功能,并使用`ViewFlipper`添加图片切换动画效果。文章提供了完整的代码示例,包括XML布局、动画文件和Java代码,最终展示了实现效果。此教程适合想了解自定义View和动画效果的开发者。
221 65
Android自定义view之网易云推荐歌单界面
|
5月前
|
XML 前端开发 Android开发
一篇文章带你走近Android自定义view
这是一篇关于Android自定义View的全面教程,涵盖从基础到进阶的知识点。文章首先讲解了自定义View的必要性及简单实现(如通过三个构造函数解决焦点问题),接着深入探讨Canvas绘图、自定义属性设置、动画实现等内容。还提供了具体案例,如跑马灯、折线图、太极图等。此外,文章详细解析了View绘制流程(measure、layout、draw)和事件分发机制。最后延伸至SurfaceView、GLSurfaceView、SVG动画等高级主题,并附带GitHub案例供实践。适合希望深入理解Android自定义View的开发者学习参考。
545 84
|
3月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
170 11
|
3月前
|
移动开发 Java 编译器
Kotlin与Jetpack Compose:Android开发生态的演进与架构思考
本文从资深Android工程师视角深入分析Kotlin与Jetpack Compose在Android系统中的技术定位。Kotlin通过空安全、协程等特性解决了Java在移动开发中的痛点,成为Android官方首选语言。Jetpack Compose则引入声明式UI范式,通过重组机制实现高效UI更新。两者结合不仅提升开发效率,更为跨平台战略和现代架构模式提供技术基础,代表了Android开发生态的根本性演进。
112 0

热门文章

最新文章