学习资料:Android开发艺术探索
和Android应用开发之所有动画使用详解
1.Android中的三种动画
- View动画
通过场景里的对象不断做图像变换(平移,缩放,旋转,透明度)从而产生动画效果,是一种渐近式动画,并支持自定义。
- 帧动画
帧动画其实也属于
View
动画。通过顺序播放一系列图像从而产生动画效果,可以简单理解为图片切换动画效果,但图片过多过大会导致OOM
- 属性动画
属相动画通过动态地改变对象的属性从而达到动画效果。
重点在于属性动画的学习
2.View动画
View
动画的作用对象是View
。支持四种典型动画效果:
- 平移动画
TranslateAnimation
- 缩放动画
ScaleAnimation
- 旋转动画
RotateAnimation
- 透明度动画
AlphaAnimation
对于
View
动画,建议采用xml
来定义动画,这样可读性更好
View
动画的四种变换
名称 | 标签 | 子类 | 效果 |
---|---|---|---|
平移动画 | <translate> |
TranslateAnimation |
移动View
|
缩放动画 | <scale> |
ScaleAnimation |
放大或缩小View
|
旋转动画 | <rotate> |
RotateAnimation |
旋转View
|
透明度动画 | <alpha> |
AlphaAnimation |
改变View 的透明度 |
Animation
属性:
xml属性 | jav代码 | 作用 |
---|---|---|
android:detachWallpaper |
setDetachWallpaper(boolean) |
是否在壁纸上运行 |
android:duration |
setDuration(long) |
动画的持续时间 |
android:fillAfter |
setFillAfter(boolean) |
动画结束后是否停留在结束位置 |
android:fillBefore |
setFillBefore(boolean) |
动画结束时是否还原开始位置 |
android:fillEnabled |
setFillEnabled(boolean) |
同上,与fillBefore相同 |
android:interpolator |
setInterpolator(Interpolator) |
设置插值器 |
android:repeatCount |
setRepeatCount(int) |
重复次数 |
android:repeatMode |
setRepeatMode(int) |
有两种重复类型,reverse 倒序回放,restart 从头播放 |
android:startOffset |
setStartOffset(long) |
开启动画startAnimation(animation) 之后等待执行运行动画的时间 |
android:zAdjustment |
setZAdjustment(int) |
表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal ),默认为normal
|
View
动画既可以是单个动画,也可以是一些列动画组成。
<set>
标签标示动画集合,对应于AnimationSet
类,可以包含若干动画,也可以嵌套其他的动画集合。
android:interpolator
动画集合所采用的的插值器,插值器影响动画的速度,比如非匀速动画就需要通过插值器来控制动画的播放过程。默认为@android:anim/accelerate_decelerate_interpolator
,即加速加速插值器。
-
android:shareInterpolator
集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,子动画就需要单独指定所需的插值器或者使用默认值。
2.1TranslateAnimation
平移动画
可以简单实现抖动效果,转成
gif
掉帧有点严重,没有抖起来
在res
下创建anim
文件夹,文件名translate_animation.xml
xml
文件代码:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="false"
android:duration="100"
android:repeatMode="restart"
>
<translate
android:repeatCount="2"
android:fromXDelta="-10"
android:fromYDelta="-5"
android:toXDelta="10"
android:toYDelta="5" />
</set>
java
代码:
Button bt = (Button) view.findViewById(R.id.bt_translate_fragment_translate);
ImageView iv = (ImageView)view.findViewById(R.id.iv_translate_fragment_translate);
//初始化动画
Animation animation = AnimationUtils.loadAnimation(context, R.anim.translate_animation);
//点击按钮开始动画
bt.setOnClickListener((v) -> iv.startAnimation(animation));
-
android:fromXDelta
x的起始坐标值,可以为数值、百分数、百分数p
。以View
的左上角为坐标系原点。负为左,正为右。
- 数值: 10表示以当前View左上角坐标加10px为初始点
- 百分数: 50%表示以当前View的左上角加上当前View宽高的50%做为初始点
- 百分数
p
: 50%p表示以当前View的左上角加上父控件宽高的50%做为初始点
-
android:toXDelta
x的结束坐标值 -
android:fromYDelta
y的起始坐标值。负为上,正为下 -
android:toYDelta
y的结束坐标值
需要注意的是,TranslateAnimation
动画并不会改变View
的位置布局属性。
例如,利用TranslateAnimation
把一个Button
改变了,点击移动后的Button
是无效的,而点击Button
移动前的原始空白位置会响应Button
的点击事件。
2.2ScaleAnimation
缩放动画
xml
代码:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:fillAfter="false"
android:repeatMode="reverse">
<scale
android:fromXScale="0.5"
android:fromYScale="0.5"
android:pivotX="-100"
android:pivotY="-100"
android:repeatCount="2"
android:toXScale="1"
android:toYScale="1" />
</set>
android:fromXScale
水平方向的缩放值,数字代表比例。1.0是不缩放android:fromYScale
垂直方向的缩放值android:toXScale
水平方向的结束值android:toYScale
垂直方向的结束值android:pivotX
缩放的轴点的x轴的坐标。轴点为View
的左上角android:pivotY
缩放的轴点的y轴的坐标
默认情况下轴点为
View
的中心点
感觉书上这里和我实际测试有些出入,我感觉默认是View
的左上角。不晓得是我哪里搞错了,希望可以指出。感觉坐标系就是自己上面画的那个1.0坐标图
。
2.2RotateAnimation
旋转动画
xml
代码:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:repeatMode="reverse">
<rotate
android:fromDegrees="0"
android:pivotX="235"
android:pivotY="150"
android:repeatCount="2"
android:toDegrees="360" />
</set>
-
android:fromDegrees
旋转开始的角度 -
android:toDegrees
旋转结束的角度 -
android:pivotX
旋转的轴点的x坐标 -
android:pivotY
旋转的轴点的y坐标
2.4AlphaAnimation
透明度动画
xml
代码:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:repeatMode="reverse">
<alpha
android:fromAlpha="1.0"
android:repeatCount="2"
android:toAlpha="0.1" />
</set>
-
android:fromAlpha
透明度的起始值,1.0
代表最不透明,值越小越透明 -
android:toAlpha
透明度的结束值
3. 帧动画
帧动画是顺序播放一组预先定义好的图片,类似播放电影。需要用到AnimationDrawable
这个类。
随便百度的吾王,一点没有表现出吾王美如画
。
帧动画使用步骤:
- 先在
drawable
文件下,定义一个animation-list
文件,文件名字frames_animation.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item
android:drawable="@drawable/a"
android:duration="500" />
<item
android:drawable="@drawable/b"
android:duration="500" />
<item
android:drawable="@drawable/c"
android:duration="500" />
</animation-list>
- 将
Drawable
作为View
的背景播放
private void initView() {
ImageView iv = (ImageView) findViewById(R.id.iv_frames_animation_activity);
Button bt_start= (Button) findViewById(R.id.bt_start_frames_animation_activity);
Button bt_stop= (Button) findViewById(R.id.bt_stop_frames_animation_activity);
iv.setBackgroundResource(R.drawable.frames_animation);
AnimationDrawable animation = (AnimationDrawable) iv.getBackground();
bt_start.setOnClickListener((v)-> animation.start());
bt_stop.setOnClickListener((v)->animation.stop());
}
帧动画使用很简单,但很容易出现OOM。尽量避免使用较大较多的图片。
4.View
动画的特殊使用场景
View
动画除了四种基本使用场景外,还可以在ViewGroup
中控制子元素的出场效果,在Activity
中可以实现不同Activity
之间的切换效果。
4.1 LayoutAnimation
简单介绍
LayoutAnimation
作用于ViewGroup
,为ViewGroup
指定一个动画,这样当它的子元素出场时,都会具有这种动画效果。这种效果常常用于ListView
上。
挖坑:RecyclerView
子item
的动画效果如何实现?
使用步骤:
1.指定子View
的动画
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:repeatMode="reverse">
<rotate
android:fromDegrees="0"
android:pivotX="235"
android:pivotY="150"
android:repeatCount="2"
android:toDegrees="360" />
</set>
用的是2.2
旋转的动画
2. 定义LayoutAnimation
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/rotate_animation"
android:animationOrder="reverse"
android:delay="1" />
android:animation
指定子元素入场显示的动画
android:animationOrder
子元素动画的顺序。有:
nomal
,reverse
,random
nomal
顺序显示,排在前面的子元素先显示动画;
reverse
逆序显示,排在后面的子元素先显示动画;
random
随机显示子元素的动画
android:delay
子元素开始动画的时间延迟。比如子元素的入场动画周期为300ms,0.5就表示每个子元素都需要延迟150ms。第一个进来延迟150ms,播放入场动画,第二个子元素延迟300ms播放入场动画。依次类推。
3.ViewGroup
使用LayoutAniimation
采用布局文件的形式,指定android:layoutAnimation
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layoutAnimation="@anim/layout_anim"
android:orientation="vertical"
>
<ImageView style="@style/img" />
<ImageView style="@style/img" />
<ImageView style="@style/img" />
</LinearLayout>
也可以通过代码来实现:
Animation animation= AnimationUtils.loadAnimation(context,R.anim.resId);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(1);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
目标ViewGroup.setLayoutAnimation(controller);
4.2Activity
的切换效果
使用overidePendingTransition(int enterAnim, int exitAnim)
可以改变Activity
的的默认切换效果。这个方法 必须在startActivity()
或者finish()
之后才有效果。
enterAnim
Activity
被打开时所需的动画资源id
exitAnim
Activity
被暂停时所需的动画资源id
启动一个Activity
时:
Intent intent = new Intent(MainActivity.this, activity);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
退出一个Activity
时:
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
5.最后
下篇学习属性动画。周末填4.1
挖的坑,学习RecyclerView
如何为子item
添加动画效果