- View 动画(补间动画)
- 帧动画
一.View 动画
View动画通过对场景里的对象不断做图像变换(平移/缩放/旋转/透明度)从而产生动画效果,它是一种渐进式动画,并且View动画支持自定义.View动画的View移动只是视觉效果,并不能改变View的位置.
1.View动画的种类
View动画的四种变换效果对应着Animation的四个子类:TranslateAnimation,ScaleAnimation,RotateAnimation和AlphaAnimation.这四种动画既可以通过XML来定义,也可以通过代码来动态创建.对应的关系如图:
(1)XML方式定义View动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"//插值器,影响动画速度,这里是加速减速插值器
android:shareInterpolator=["true" | "false"]//表示集合中的动画是否共享插值器
android:fillAfter="true"//动画结束后View是否停留在结束位置
android:duration="1000">//动画持续的时间
<alpha
android:fromAlpha="floate"//表示透明度的起始值,比如0.1
android:toAlpha="floate"/>//表示透明度的结束值,比如1,从0到1中取值,0表示完全透明,1表示完全不透明
<scale
android:fromXScale="floate"//水平方向缩放的起始值,比如0.5
android:toXScale="floate"//水平方向缩放的结束值,比如1.2
android:fromYScale="floate"//竖直方向缩放的起始值
android:toYScale="floate"//竖直方向缩放的结束值
android:pivotX="floate"//缩放轴点的x坐标,从0%到100%中取值
android:pivotY="floate"/>//缩放轴点的y坐标
<translate
android:fromXDelta="floate"//表示x的起始值,比如0
android:toXDelta="floate"//表示x的结束值,比如100
android:fromYDelta="floate"//表示y的起始值
android:toYDelta="floate"/>//表示y的结束值
[这四个属性取值可以是数值/百分比/百分比p,例如:]
[50:以View左上角为原点沿坐标轴正方向偏移50px]
[50%:以View左上角为原点沿坐标轴正方向偏移View宽/高度的50%]
[50%p:以View左上角为原点沿坐标轴正方向偏移父(parent)控件宽/高度的50%]
<rotate
android:fromDegrees="floate"//旋转开始的角度,比如0
android:toDegrees="floate"//旋转结束的角度,比如180,这里为正数表示顺时针旋转,为负数表示逆时针旋转
android:pivotY="floate"//旋转的轴点x的坐标
android:pivotX="floate"/>//旋转的轴点的y的坐标
</set>
View动画一些共有的属性:
注意:<set>
标签表示动画集合,对应AnimationSet类,它可以包含若干个动画,其内部也可以嵌套其它动画集合.
下面是一个实际例子:
//res/anim/anim_set.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true"
android:zAdjustment="normal">
<translate
android:duration="100"
android:interpolator="@android:anim/linear_interpolator"
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:toYDelta="100"/>
<rotate
android:duration="400"
android:fromDegrees="0"
android:toDegrees="90"/>
</set>
ImageView imageView = findViewById(R.id.img);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_set);
imageView.startAnimation(animation);
注意:对于View动画来说,建议采用XML来定义动画,这是因为XML格式的动画可读性更好.
(2)代码方式实现View动画
AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(1000);
imageView.startAnimation(alphaAnimation);
(3)View动画监听
通过Animation的setAnimationListener方法可以给View动画添加过程监听,如下所示:
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
(4)自定义View动画
自定义View动画只需要继承Animation抽象类,然后重写它的initialize和applyTransformation方法,在initialize中做一些初始化操作,在applyTransformation中进行相应的矩阵变化.这里主要参考实例Android动画系列之自定义补间动画
(5)View动画的特殊使用场景
a.LayoutAnimation
LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,这样当它的子元素出场时都会具有这种的动画效果.
通过xml的方式来实现,如下所示:
// res/anim/anim__layout.xml
<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"//子元素开始动画的时间延迟
android:animationOrder="normal"//子元素动画的顺序,normal表示顺序显示,reverse表示逆向显示,random表示随机
android:animation="@anim/anim_item">//为子元素指定具体的入场动画
</layoutAnimation>
// res/anim/anim_item.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true">
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0"/>
<translate
android:fromXDelta="500"
android:toXDelta="0"/>
</set>
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/anim_layout"
android:background="@color/colorAccent"
android:cacheColorHint="#00000000"
android:divider="#ddddbdb"
android:dividerHeight="1.0dp"
android:listSelector="@android:color/transparent"></ListView>
通过代码的方式实现,如下所示:
ListView listView = findViewById(R.id.list);
Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.anim_layout);
LayoutAnimationController layoutAnimationController = new LayoutAnimationController(animation1);
layoutAnimationController.setDelay(0.5f);
layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(layoutAnimationController);
b.Activity的切换效果
自定义Activity的切换效果,主要用到的是overridePendingTransition(int enterAnim, int exitAnim)方法,enterAnim表示Activity被打开时的动画,exitAnim表示Activity被暂停时的动画,这个方法必须在startActivity(Intent)和finish()之后调用.
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
@Override
public void finish() {
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
另外Fragment也可以添加切换动画,主要是通过FragmentTransaction中的setCustomAnimations()方法来添加切换动画.
二.帧动画
帧动画是顺序播放一组预先定义好的图片,系统提供了AnimationDrawable类来使用帧动画.其实帧动画也属于View动画,只是表现形式有点不太一样.
// res/drawable/frame_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_launcher_background" android:duration="500"/>
<item android:drawable="@drawable/clip" android:duration="500"/>
<item android:drawable="@drawable/scale" android:duration="500"/>
</animation-list>
imageView.setBackgroundResource(R.drawable.frame_anim);
AnimationDrawable drawable = (AnimationDrawable) imageView.getBackground();
drawable.start();
注意:使用帧动画不能使用尺寸过大的图片,容易OOM.