一直对画画相关不感冒,但是Android的动画机制还是要硬着头皮拿下
先看看各种动画的效果,界面很丑
Android提供了AlphaAnimation,RotateAnimatio,TranslateAnimation,ScaleAnimation四种动画方式,并提供了Animationset动画集合,混合使用多种动画,有动画肯定就有动画在各个状态的监听
case R.id.alpha:// 透明动画
AlphaAnimation al = new AlphaAnimation(0, 1);
al.setDuration(2000);
alpha.startAnimation(al);
// 动画监听
al.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
Log.i("slack", "onAnimationStart");
}
@Override
public void onAnimationEnd(Animation animation) {
Log.i("slack", "onAnimationEnd");
Toast.makeText(MainActivity.this, "动画结束", Toast.LENGTH_LONG).show();
}
@Override
public void onAnimationRepeat(Animation animation) {
Log.i("slack", "onAnimationRepeat");
}
});
break;
case R.id.rotate:// 旋转动画
// RotateAnimation (float fromDegrees, float toDegrees, float pivotX, float pivotY)
RotateAnimation ro = new RotateAnimation(0, 180, 100, 100);
ro.setDuration(2000);
// rotate.setAnimation(ro);
rotate.startAnimation(ro);
break;
case R.id.translate: // 平移动画
// TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
TranslateAnimation tr = new TranslateAnimation(0, 200, 0, 300);
tr.setDuration(2000);
// translate.setAnimation(tr);
// want the animation to play immediately
translate.startAnimation(tr);
tr.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
// 再移回来
TranslateAnimation tr = new TranslateAnimation(200, 0, 300, 0);
tr.setDuration(2000);
translate.startAnimation(tr);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
break;
case R.id.scale:// 缩放动画
// ScaleAnimation (float fromX, float toX, float fromY, float toY)
ScaleAnimation sc = new ScaleAnimation(0, 2, 0, 2);
sc.setDuration(2000);
scale.startAnimation(sc);
break;
case R.id.set:// AnimationSet 动画集合
AnimationSet setAnimation = new AnimationSet(true);
setAnimation.setDuration(2000);
AlphaAnimation als = new AlphaAnimation(0, 1);
als.setDuration(2000);
setAnimation.addAnimation(als);
RotateAnimation ros = new RotateAnimation(0, 360, 100, 100);
ros.setDuration(2000);
setAnimation.addAnimation(ros);
ScaleAnimation scs = new ScaleAnimation(0, 1, 0, 1);
scs.setDuration(2000);
setAnimation.addAnimation(scs);
set.startAnimation(setAnimation);
break;
ObjectAnimator
case R.id.object:// 使用ObjectAnimator进行更精细化的控制,操作单个属性
/**
* translationX和 translationY:这两个属性作为一种增量来控制着View对象从它布局容器的左上角坐标偏移的位置。
* rotation、rotationX和rotationY:这三个属性控制View对象围绕支点进行2D和3D旋转
* scaleX和scaleY. 这两个属性控制着View对象围绕它的支点进行2D缩放。
* pivotX和pivotY:这两个属性控制着view对象的支点位置,围绕这个支点进行旋转和缩放变换处理,
默认情况下,该支点的位置就是View对象的中心点。
* x和y这是两个简单实用的属性,它描述了View对象在它的容器中的最终位置,
它是最初的左上角坐标和 translationX和 translationY值的累计和
* alpha:它表示View对象的alpha透明度,默认值是1(不透明),0代表完全透明(不可见)
* 需要注意的是,这里操作的属性要有 set,get的方法,如果自己自定义一个动画类,需要提供属性的get/set方法
* */
ObjectAnimator ob = ObjectAnimator.ofFloat(object, "translationX", 300);
ob.setDuration(2000);
ob.start();
ob.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
// 还原
ObjectAnimator.ofFloat(object, "translationX", 0).setDuration(2000).start();
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
break;
PropertyValuesHolder
case R.id.property:// 类似视图动画中的AnimationSet,就是把动画给组合起来
PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("rotation",30);// 30°
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX",1f,0,1.2f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY",1f,1,1f);// 属性,开始变化的大小,是否变化到最小(1 no, 0 yes),结束变化后的大小
ObjectAnimator.ofPropertyValuesHolder(property,pvh1,pvh2,pvh3).setDuration(2000).start();
// ObjectAnimator.ofPropertyValuesHolder(property,pvh3).setDuration(2000).start();
break;
ValueAnimator
case R.id.value:// ObjectAnimator也是继承自ValueAnimator
//ValueAnimator本身不提供任何动画,他更像是一个数值发生器,
// 用来产生一定具有规律的数字,从而让调用者控制动画的整个过程
ValueAnimator va = ValueAnimator.ofFloat(0, 50);
va.setTarget(value);
va.setDuration(2000).start();
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float values = (float) animation.getAnimatedValue();
Log.i("slack", "values:"+values );
}
});
//只监听动画结束
va.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
Log.i("slack", "done..." );
}
});
break;
AnimatorSet
case R.id.animatorSet:// 对于一个属性同时作用在一个view上,跟PropertyValuesHolder一样,但是AnimatorSet不仅能实现,而且能更精准的控制顺序
ObjectAnimator animator1 = ObjectAnimator.ofFloat(animatorSet, "rotation", 30);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(animatorSet, "scaleX", 1f, 0, 2f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(animatorSet, "scaleY", 1f, 0, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(2000);
// set.playTogether(animator1, animator2, animator3);// 通过playTogether等方法控制多个动画协同工作,从而控制播放顺序
set.playSequentially(animator1, animator2, animator3);// 依次动画
set.start();
break;
animate
case R.id.animate:// animate方法直接来驱动属性动画
animate.animate().alpha(0).y(300).x(100).setDuration(2000).withStartAction(new Runnable() {
@Override
public void run() {
}
}).withEndAction(new Runnable() {
@Override
public void run() {
}
}).start();
break;
使用XML 文件定义动画res/animator/animator.xml
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:propertyName="scaleX"
android:valueFrom="1.0"
android:valueTo="2.0"
android:valueType="floatType">
</objectAnimator>
java调用
case R.id.fromXML:// 属性动画同样的可以定义在xml
Animator anim = AnimatorInflater
.loadAnimator(this, R.animator.animator);
anim.setTarget(fromXML);
anim.start();
android 里 使用 SVG
SVG命令详解:
M (x y) 移动到x,y
L (x y) 直线连到x,y,还有简化命令H(x) 水平连接、V(y)垂直连接
Z,没有参数,连接起点和终点
C(x1 y1 x2 y2 x y),控制点x1,y1 x2,y2,终点x,y
Q(x1 y1 x y),控制点x1,y1,终点x,y
A(rx ry x-axis-rotation large-arc-flag sweep-flag x y)
rx ry 椭圆半径
x-axis-rotation x轴旋转角度
large-arc-flag 为0时表示取小弧度,1时取大弧度
sweep-flag 0取逆时针方向,1取顺时针方向
有个图解:

在线 SVG 编辑器:http://editor.method.ac/
使用SVG官方有说明:https://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html
主要需要三个文件:
1.VectorDrawable定义的是一张静态图,
2.AnimatedVectorDrawable,可以让矢量图有动画效果,
3.定义动画文件
最后是一个下拉动画,使用的是ValueAnimator,使用其产生一定具有规律的数字来实现淡出和淡入效果