Android中的动画机制
1 逐帧动画
逐帧动画 就是一系列的图片按照一定的顺序展示的过程。
逐帧动画很简单, 只需要在drawable中或者anim中定义一个Animation-list 其中包含多个item,每个item中包含一个图片 和duration
eg:
<?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/pic1" android:duration="500"/>
<item android:drawable="@drawable/pic2" android:duration="500"/>
<item android:drawable="@drawable/pic3" android:duration="500"/>
<item android:drawable="@drawable/pic4" android:duration="500"/>
<item android:drawable="@drawable/pic5" android:duration="500"/>
<item android:drawable="@drawable/pic6" android:duration="500"/>
<item android:drawable="@drawable/pic7" android:duration="500"/>
<item android:drawable="@drawable/pic8" android:duration="500"/>
<item android:drawable="@drawable/pic9" android:duration="500"/>
</animation-list>
其中oneshot 表示是不是只循环一次
在Activity中只需要获得AnimationDrawable 调用start即可
public void startAnimation(View view)
{
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.start();
}
public void stopAnimation(View view)
{
AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getBackground();
animationDrawable.stop();
}
其中的imageView已经指定了背景 即animation-list
<ImageView
android:id="@+id/image_Ani"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="@drawable/animation_list" />
如果设置图片是android:src="@drawable/animation_list", 那么获得AnimationDrawable 使用imageView.getDrawable();
当然 也可以不用资源文件来定义图片列表,完全用代码去实现
AnimationDrawable drawable = new AnimationDrawable();
drawable.addFrame(getDrawable(R.drawable.pic1), 500);
drawable.addFrame(getDrawable(R.drawable.pic2), 500);
drawable.addFrame(getDrawable(R.drawable.pic2), 500);
imageView.setImageDrawable(drawable);
drawable.start();
2. 补间动画
补间动画也叫视图动画,指的是视图在容器内可以做一系列简单的变化,比如说ImageView可以简单的变化(淡入淡出,旋转,平移,缩放)
补间动画可以在anim中定义xml文件,也可以用代码实现,但是建议用xml实现,这样就会有可重用性
AlphaAnimation <alpha> 放置在res/anim/目录下 渐变透明度动画效果
RotateAnimation <rotate> 放置在res/anim/目录下 画面转移旋转动画效果
ScaleAnimation <scale> 放置在res/anim/目录下 渐变尺寸伸缩动画效果
TranslateAnimation <translate> 放置在res/anim/目录下 画面转换位置移动动画效果
AnimationSet <set> 放置在res/anim/目录下 一个持有其它动画元素alpha、scale、translate、rotate或者其它set元素的容器
所有animation的通用的属性:
android:detachWallpaper setDetachWallpaper(boolean) 是否在壁纸上运行
android:duration setDuration(long) 动画持续时间,毫秒为单位
android:fillAfter setFillAfter(boolean) 控件动画结束时是否保持动画最后的状态
android:fillBefore setFillBefore(boolean) 控件动画结束时是否还原到开始动画前的状态
android:fillEnabled setFillEnabled(boolean) 与android:fillBefore效果相同
android:interpolator setInterpolator(Interpolator) 设定插值器(指定的动画效果,譬如回弹等)
android:repeatCount setRepeatCount(int) 重复次数
android:repeatMode setRepeatMode(int) 重复类型有两个值,reverse表示倒序回放,restart表示从头播放
android:startOffset setStartOffset(long) 调用start函数之后等待开始运行的时间,单位为毫秒
android:zAdjustment setZAdjustment(int) 表示被设置动画的内容运行时在Z轴上的位置(top/bottom/normal),默认为normal
AlphaAnimation动画
float fromAlpha
float toAlpha
透明度,从0 到1:
eg:
AlphaAnimation animation = new AlphaAnimation(1, 0);
animation.setDuration(1000);
animation.setRepeatCount(6);
imageView.startAnimation(animation);
XML 实现:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="3000"/>
</set>
调用:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.scale);
imageView.startAnimation(animation);
当然在set中可以组合其他的动画,比如说rotation, translate,scale。
ScaleAnimation: 缩放动画
float fromX 表是从哪个比例开始缩放,取值1到0, 1表示正常大小
float toX 表示缩放到哪个范围 取值1到0, 1表示正常大小
float fromY 沿Y轴 同上
float toY
float pivotX 相对于x轴的缩放的位置
float pivotY
eg:
ScaleAnimation animation = new ScaleAnimation(0.5f, 1, 0.5f,1,500,500);
animation.setDuration(3000);
imageView.startAnimation(animation);
RotateAnimation:旋转动画
float fromDegrees
float toDegrees 旋转的度数, 正数表示顺时针旋转,负数表示逆时针旋转
float pivotX 旋转的中心点
float pivotY
eg:
RotateAnimation animation = new RotateAnimation(0, 360,500, 500);
animation.setDuration(2000);
imageView.startAnimation(animation);
TranstlateAnimation: 平移动画
float fromXDelta 平移的起始坐标
float toXDelta
float fromYDelta
float toYDelta
eg:
TranslateAnimation animation = new TranslateAnimation(0, 400, 0, 0);
animation.setDuration(2000);
imageView.startAnimation(animation);
AnimationSet: 各种动画的组合
eg:
AnimationSet animationSet = new AnimationSet(true);
AlphaAnimation animation = new AlphaAnimation(1, 0);
animation.setDuration(2000);
ScaleAnimation animation1 = new ScaleAnimation(0.5f, 1, 0.5f,1);
animation1.setDuration(3000);
RotateAnimation animation2 = new RotateAnimation(0, 360,400, 400);
animation2.setDuration(2000);
TranslateAnimation animation3 = new TranslateAnimation(0, 400, 0, 0);
animation3.setDuration(2000);
animationSet.addAnimation(animation);
animationSet.addAnimation(animation1);
animationSet.addAnimation(animation2);
animationSet.addAnimation(animation3);
imageView.startAnimation(animationSet);
Android 中的属性动画
属性动画可以对对象的属性进行操作,也就是说在一个时间间隔内完成对对象的属性从一个值到另个一个值得转变,因此属性动画的功能是很强大的,只有你有这个属性,就能实现动画效果. 当然,因为属性动画其实利用的是反射原理,所以对于这个属性必须要有get,set方法才能操作成功,否则说不好会crash。
属性动画 最重要的是三个类 AnimatorSet, ObjectAnimator和ValueAnimator。
ValueAnimator类似于一个平滑过渡的产生器。
eg:
ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
valueAnimator.setDuration(300);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int value = valueAnimator.getAnimatedValue()
}
});
valueAnimator.start();
start 之后 在300毫秒之内,这个valueAnimator会从1走到100,产生的值赋值给value。所以 如果我们想 自己实现一些动画,比如说一个控件的空度的改变,那么只需要在onAnimationUpdate这个方法中不断的去设置其宽度的值,就可以实现平滑的改变。
ObjectAnimator继承自ValueAnimator. ObjectAnimator 实际上就是封转了类似我们上面说的宽度改变的动画。ObjectAnimator 内部用的是反射,所以我们需要的是传递给ObjectAnimator是空间的属性,以及value值得变化,所以就要求这个属性一定要有get,set方法。
eg:
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView,"translationX",0, 100);
animator.setDuration(6000);
animator.start();
所以补间动画能够实现的功能,我们都能够实现,比如 rotationX,rotationY, scaleX,scaleY等等。
当然如果某些属性没有 getset方法,那么怎么办呢?
谷歌给的解决方案是:
一个是通过自定义一个包装类,来间接的改变这个属性的值:
eg:
private class MyselfView{
private View view;
private int width;
public MyselfView(View view)
{
this.view = view;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
view.getLayoutParams().width = width;
view.requestLayout();
}
}
定义好这个类之后只要:
ObjectAnimator animator = ObjectAnimator.ofFloat(new MyselfView(imageView),"width",0, 100);
animator.setDuration(4000);
animator.start();
另一种方法就是利用ValueAnimator来实现了
对于AnimatorSet动画的集合 提供了paly .with,before, after等,来实现动画的先后顺序 当然也有playTogether(......)。
eg:
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(animator1).with(animator2);
属性动画也可以在XML中定义,以更具有通用性。这个xml动画要放在资源文件res/animator下
eg:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="4000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"/>
调用的时候也和补间动画类似:
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.obhectanimotr1);
animator.setTarget(imageView);
animator.start();
博客 http://blog.csdn.net/lingling1420q/article/details/38678493 还不错哦
posted on 2016-07-29 18:04 xiaodong135 阅读(216) 评论(0) 编辑 收藏 举报