文章目录
一.前言
Android的动画大致分为三种 ,分别是 逐帧动画 ,补间动画 ,属性动画
二.逐帧动画
逐帧动画的工作原理很简单,其实就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理。
步骤:
- 在res/drawable目录下定义一个XML文件,根节点为系统提供的animation-list,然后放入定义更好的图片;
- 使用AnimationDrawable类播放第一步定义好的Drawable中的图片,形成动画效果;
示例代码,第一步,创建Drawable文件:
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/image1" android:duration="500"/>
<item android:drawable="@drawable/image2" android:duration="500"/>
<item android:drawable="@drawable/image3" android:duration="500"/>
</animation-list>
说明:
- android:oneshot=“false”: 表示是否重复播放动画,还是只播放一次;
- 每个item都有Drawable和duration属性,Drawable表示我们要播放的图片;duration表示这张图播放的时间;
示例代码,第二步,用AnimationDrawable播放动画:
button = findViewById(R.id.button);
button.setBackgroundResource(R.drawable.frame_animation);//把Drawable设置为button的背景
AnimationDrawable drawable = (AnimationDrawable) button.getBackground();//拿到这个我们定义的Drawable,实际也就是AnimationDrawable
drawable.start();//开启动画
**注意:**在使用帧动画是应该尽量避免使用过多尺寸较大的图片,否则容易引起OOM
三.补间动画
补间动画的介绍
我们只需要拿到一个view,设定它开始和结束的位置,中间的view会自动由系统补齐,而不需要帧动画每一幅图都是提前准备好的。
补间动画是Android一开始就提供的比较原始的动画,主要支持四种效果:平移、缩放、旋转、透明度变化(渐变) 四种基本效果,我们可以再这四种基础效果的基础上,选择其中的几种进行组合。
View动画的四种基本效果对应了四个Animation的子类,如下:
补间动画的使用
单个使用
第一步创建动画的xml文件
- 平移动画(需要把xml文件放在res/anim目录)
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100" //水平开始点的坐标
android:fromYDelta="0"
android:toXDelta="0" //水平结束点的坐标
android:toYDelta="0"/>
- 缩放动画
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000" //动画的时间间隔
android:fromXScale="0.0" //水平缩放的起始值
android:fromYScale="0.0"
android:pivotX="50%" //pivotX和pivotY表示以缩放中心的位置。
android:pivotY="50%"
android:toXScale="1.0" //水平方向缩放的结束值
android:toYScale="1.0"/>
- 旋转动画
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegree="0" //开始旋转的角度
android:toDegree="1800" //
android:pivotX = "50%"
android:pivotY="50%"
android:duration = "3000"
/>
- 渐变动画
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000" //动画的持续时间
android:fromAlpha="1.0" //透明度的起始值
android:fillAfter = true //动画结束之后View是否停留在结束位置
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toAlpha="0.0" //透明度的结束值
/>
注意点:
interpolator表示动画插值器, 可以控制动画的变化速率, 比如前200ms很慢,中间600ms很快,最后200ms又很慢。
pivot 这个属性主要是在translate 和 scale 动画中,这两种动画都牵扯到view 的“物理位置“发生变化,所以需要一个参考点。 而pivotX和pivotY就共同决定了这个点;它的值可以是float或者是百分比数值。
以 pivotX 为例,说明其取不同的值的含义:
- 10:距离动画所在view自身左边缘10像素
- 10% :距离动画所在view自身左边缘 的距离是整个view宽度的10%
- 10%p:距离动画所在view父控件左边缘的距离是整个view宽度的10%
** 第二步,使用**
Animation animation = AnimationUtils.loadAnimation(this, R.anim.filename);
textView.startAnimation(animation);
** 也可用代码完成不借助xml文件**
AlphaAnimation alphaAnimation = new AlphaAnimation(0,1);
alphaAnimation.setDuration(2000);
//设置动画的监听
alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
Animation animation1= AnimationUtils.loadAnimation(MainActivity.this, R.anim.filename);
textView.startAnimation(animation1);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
textView.startAnimation(alphaAnimation);
嵌套使用
我们可以使用AnimationSet把View动画的平移、缩放、旋转、渐变都揉在一起,也是既能通过代码实现,也可以通过xml实现
xml实现:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
>
<scale
android:duration="3000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
<alpha
android:duration="3000"
android:fromAlpha="1.0"
android:toAlpha="0.5" />
<rotate
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX = "50%"
android:pivotY="50%"
android:duration = "3000"
/>
<translate
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:toYDelta="100" />
</set>
代码实现:
AnimationSet setAnimation = new AnimationSet(true);
// 特别说明以下情况
// 因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
// 所以动画不会结束,而是无限循环
// 所以组合动画的下面两行设置是无效的, 以后设置的为准
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);// 设置了循环一次,但无效
// 旋转动画
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 平移动画
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 透明度动画
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 缩放动画
Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale1.setDuration(1000);
scale1.setStartOffset(4000);
// 将创建的子动画添加到组合动画里
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale1);
// 使用
mButton.startAnimation(setAnimation);
View动画的特殊使用场景
1.LayoutAnimation
LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,然后,当它的子元素出场时都会具有这种效果。这种效果常被用于ListView,有的ListView的每个item都以一定的动画形式出现,用到的就是LayoutAnimation。
使用步骤:
- 定义LayoutAnimation的xml文件;
- 指定具体的入场动画;
- 为ViewGroup指定android:layoutAnimation属性,引用这个LayoutAnimation的xml文件;
第一步: 定义LayoutAnimation的xml文件;
// res/anim/anim_layout.xml
<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"/>
第二步: 指定具体的入场动画;
// 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>
第三步: 为ViewGroup指定android:layoutAnimation属性;
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/anim_layout"
android:background="#fff4f7f9"
android:cacheColorHint="#00000000"
android:divider="#dddbdb"
android:dividerHeight="1.0px"
android:listSelector="@android:color/transparent" />
单用代码实现:
ListView listView = (ListView) layout.findViewById(R.id.list);
Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_
item);
LayoutAnimationController controller = new LayoutAnimationController
(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
2.Activity的切换效果
Activity有默认的切换效果,但是我们可以定制,主要用到overridePendingTransition(int enterAnima, int exitAnima)这个方法:
当启动一个Activity时
Intent intent = new Intent(this,TestActivity.class);
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);
}
注意:
overridePendingTransition这个方法必须位于startActivity或者finish后面,否则动画会没有效果。
Fragment的切换效果:可以使用FragmentTransaction的setCustomAnimation方法添加切换动画。