Android动画效果
1 章节目录
1.1 目标
-
帧动画
-
补间动画
1.2 重点
-
帧动画
-
补间动画
1.3 难点
-
帧动画
-
补间动画
2 动画
在APP中添加上一些动画,会让我们的应用变得 很炫,比如最简单的关开Activity,当然自定义控件动画肯定必不可少啦~而Android中的动画 分为三大类,逐帧动画(Frame)以及补间动画(Tween),还有Android 3.0以后引入的属性动画(Property)
3 帧动画
3.1 帧动画简介
帧动画非常容易理解,其实就是简单的由N张静态图片收集起来,然后我们通过控制依次显示 这些图片,因为人眼"视觉残留"的原因,会让我们造成动画的"错觉",跟放电影的原理一样!
而Android中实现帧动画,一般我们会用到前面讲解到的一个Drawable:AnimationDrawable先编写好Drawable,然后代码中调用start()以及stop()开始或停止播放动画
当然我们也可以在Java代码中创建逐帧动画,创建AnimationDrawable对象,然后调用 addFrame(Drawable frame,int duration)向动画中添加帧,接着调用start()和stop()而已
3.2 帧动画的使用效果(一)
代码实现:
首先编写activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始" />
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止" />
<ImageView
android:id="@+id/img_show"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center"
android:background="@anim/miao_gif" />
</LinearLayout>
接下来编写我们的动画文件,非常简单,先在drawable目录下,接着开始撸我们的 动画文件:miao_gif.xml: 这里的android:oneshot是设置动画是否只是播放一次,true只播放一次,false循环播放!
动画文件有了,接着到我们的布局文件:activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始" />
<Button
android:id="@+id/btn_stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止" />
<ImageView
android:id="@+id/img_show"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_gravity="center"
android:background="@anim/miao_gif" />
</LinearLayout>
最后是我们的MainActivity.java,这里在这里控制动画的开始以及暂停:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_start;
private Button btn_stop;
private ImageView img_show;
private AnimationDrawable anim;
3.3 帧动画的使用效果(二)
在指定地方播放帧动画
代码实现:
先上activity_main2.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
依旧是先上我们的动画文件:anim_zhuan.xml:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item
android:drawable="@mipmap/img_zhuan1"
android:duration="80" />
<item
android:drawable="@mipmap/img_zhuan2"
android:duration="80" />
<item
android:drawable="@mipmap/img_zhuan3"
android:duration="80" />
<!--限于篇幅,省略其他item,自己补上-->
...
</animation-list>
接着我们来写一个自定义的ImageView:FrameView.java,这里通过反射获得当前播放的帧, 然后是否为最后一帧,是的话隐藏控件!
public class FrameView extends ImageView {
private AnimationDrawable anim;
public FrameView(Context context) {
super(context);
}
public FrameView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FrameView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setAnim(AnimationDrawable anim){
this.anim = anim;
}
public void setLocation(int top,int left){
this.setFrame(left,top,left + 200,top + 200);
}
最后是我们的MainActivity.java,创建一个FrameLayout,添加View,对触摸事件中按下的 事件做处理,显示控件以及开启动画~
public class MainActivity extends AppCompatActivity {
private FrameView fView;
private AnimationDrawable anim = null;
4 补间动画
与前面学的帧动画不同,帧动画是通过连续播放图片来模拟动画效果,而补间动画开发者只需指定动画开始,以及动画结束"关键帧", 而动画变化的"中间帧"则由系统计算并补齐!
4.1 补间动画的分类和Interpolator
4.1.1 Andoird所支持的补间动画效果有如下这五种,或者说四种吧,第五种是前面几种的组合而已
-
AlphaAnimation:透明度渐变效果,创建时许指定开始以及结束透明度,还有动画的持续 时间,透明度的变化范围(0,1),0是完全透明,1是完全不透明;对应<alpha/>标签!
-
ScaleAnimation:缩放渐变效果,创建时需指定开始以及结束的缩放比,以及缩放参考点, 还有动画的持续时间;对应<scale/>标签!
-
TranslateAnimation:位移渐变效果,创建时指定起始以及结束位置,并指定动画的持续 时间即可;对应<translate/>标签!
-
RotateAnimation:旋转渐变效果,创建时指定动画起始以及结束的旋转角度,以及动画 持续时间和旋转的轴心;对应<rotate/>标签
-
AnimationSet:组合渐变,就是前面多种渐变的组合,对应<set/>标签
4.2.2 Interpolator
用来控制动画的变化速度,可以理解成动画渲染器,当然我们也可以自己实现Interpolator 接口,自行来控制动画的变化速度,而Android中已经为我们提供了可供选择的实现类:
渲染器 | 说明 |
---|---|
LinearInterpolator | 动画以均匀的速度改变 |
AccelerateInterpolator | 在动画开始的地方改变速度较慢,然后开始加速 |
AccelerateDecelerateInterpolator | 在动画开始、结束的地方改变速度较慢,中间时加速 |
CycleInterpolator | 动画循环播放特定次数,变化速度按正弦曲线改变: Math.sin(2 * mCycles * Math.PI * input) |
DecelerateInterpolator | 在动画开始的地方改变速度较快,然后开始减速 |
AnticipateInterpolator | 反向,先向相反方向改变一段再加速播放 |
AnticipateOvershootInterpolator | 开始的时候向后然后向前甩一定值后返回最后的值 |
BounceInterpolator | 跳跃,快到目的值时值会跳跃,如目的值100,后面的值可能依次为85,77,70,80,90,100 |
OvershottInterpolator | 回弹,最后超出目的值然后缓慢改变到目的值 |
而这个Interpolator 我们一般是在写动画xml文件时会用到,属性是:android:interpolator, 而上面对应的值是:@android:anim/linear_interpolator,其实就是驼峰命名法变下划线而已 AccelerateDecelerateInterpolator对应:@android:anim/accelerate_decelerate_interpolator!
4.2 各种补间动画的详细讲解
这里的android:duration都是动画的持续时间,单位是毫秒
4.2.1 AlphaAnimation(透明度渐变)
anim_alpha.xml:
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromAlpha="1.0"
android:toAlpha="0.1"
android:duration="2000"/>
属性解释:
fromAlpha :起始透明度
toAlpha:结束透明度
透明度的范围为:0-1,完全透明-完全不透明
4.2.2 ScaleAnimation(缩放渐变)
anim_scale.xml:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromXScale="0.2"
android:toXScale="0.2"
android:fromYScale="1.5"
android:toYScale="1.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
属性解释:
fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例
toXScale/toYScale:沿着X轴/Y轴缩放的结束比例
pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点
4.2.3 TranslateAnimation(位移渐变)
anim_translate.xml:
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromXDelta="0"
android:toXDelta="320"
android:fromYDelta="0"
android:toYDelta="0"
android:duration="2000"/>
属性解释:
fromXDelta/fromYDelta:动画起始位置的X/Y坐标
toXDelta/toYDelta:动画结束位置的X/Y坐标
4.2.4 RotateAnimation(旋转渐变)
anim_rotate.xml:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:fromDegrees="0"
android:toDegrees="360"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"/>
属性解释:
fromDegrees/toDegrees:旋转的起始/结束角度
repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动!
4.2.5 AnimationSet(组合渐变)
非常简单,就是前面几个动画组合到一起而已~
anim_set.xml:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/decelerate_interpolator"
android:shareInterpolator="true" >
<scale
android:duration="2000"
android:fromXScale="0.2"
android:fromYScale="0.2"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.5"
android:toYScale="1.5" />
<rotate
android:duration="1000"
android:fromDegrees="0"
android:repeatCount="1"
android:repeatMode="reverse"
android:toDegrees="360" />
<translate
android:duration="2000"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="320"
android:toYDelta="0" />
<alpha
android:duration="2000"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
</set>
4.3 实例
首先来个简单的布局:activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_alpha"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="透明度渐变" />
<Button
android:id="@+id/btn_scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="缩放渐变" />
<Button
android:id="@+id/btn_tran"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="位移渐变" />
<Button
android:id="@+id/btn_rotate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="旋转渐变" />
<Button
android:id="@+id/btn_set"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="组合渐变" />
<ImageView
android:id="@+id/img_show"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="48dp"
android:src="@mipmap/img_face" />
</LinearLayout>
接着到我们的MainActivity.java,同样非常简单,只需调用AnimationUtils.loadAnimation() 加载动画,然后我们的View控件调用startAnimation开启动画即可
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_alpha;
private Button btn_scale;
private Button btn_tran;
private Button btn_rotate;
private Button btn_set;
private ImageView img_show;
private Animation animation = null;