Android属性动画是为了实现比较复杂的动画而实现的,我们都知道在平常一些简单的效果都可以使用补间动画来实现,但是他也只能做一些简单的,类似缩放,移动,透明的变化等,如果要做类似抛物线,类似电子书翻页效果,等等,肯定做不了的,那么就需要用到属性动画了。
关于属性动画补充点东西,android属性动画是在3.0以后加入的,而为了兼容1.0.等等的低版本,网络上一个大神写了一个属性动画的框架,里边的类以及方法与android系统的属性动画基本完全相同。框架名称:《nineoldandroids》,
所以使用属性动画看自己需要,都可以实现相应的效果。
属性动画:
主要包含俩种
(1)、ValueAnimator:该类继承自Animator,而不同于补间动画都继承自Animation,其实从字面上就能发现,animator是动画制作者,而animation是动画的意思,也就是已经定型的,拓展程度比较小了,所以使用属性动画才是实现我们自定义动画的利器。
使用:
关于这个类的使用,
(2)、ObjectAnimator:该类继承自ValueAnimator,是对于ValueAnimator的进一步拓展,让我们可以对任意的对象都能实现动画效果。
动画名称大全:(方法中其中一个参数就是动画名称,这结传入下边的名称就好,但是注意是字符串)
1、 rotationX
以x轴来进行翻转,翻转的方向根据传入的值来判断。
2、 rotationY
以y轴来进行翻转,翻转的方向根据传入的值来判断
3、 rotation
以当前位置的中心点进行旋转,也可以说是以z轴进行旋转,旋转方向也是需要根据传入值来判断
4、 translation
沿x轴进行平移,移动方向根据传入值来进行判断,
5、 translation
沿y轴进行平移,移动方向根据传入值来进行判断,
6、 scaleX
沿x轴方向进行缩放,但是要注意传入值的正负,
如果传入值为正,那么按值进行缩放,如果是负值,那么首先会绕y轴翻转,然后进行缩放。
7、 scaleY
沿y轴方向进行缩放,但是要注意传入值的正负,
如果传入值为正,那么按值进行缩放,如果是负值,那么首先会绕x轴翻转,然后进行缩放。
8、 alpha
设置透明度,根据值的变化改变对象的透明度。实现相应的效果
(注意,名称里边没有scale)
使用:
该类的使用方式:(以下是方法源码)
创建属性动画对象
该方法第一个参数:要进行动画的对象
第二个参数 :动画名称
第三个参数 :进行动画的取值,是一个可变参数,可以是一个值,也可以是多个参数,如果是一个值,那么默认为结束的值。
(比如:ObjectAnimator.ofFloat(mBtn_login,"alpha", 0);
代表该对象从1- 0,也就是完全不透明到完全透明)
设置动画时长:
启动动画:
实例:沿y轴负方向平移40dip
ObjectAnimator animator =ObjectAnimator.ofFloat(mBtn_login,"translationY",-40);
animator.setDuration(3000);
animator.start();
使用很简单,如果只是简单的效果是看不出属性动画强大的地方的,实现些比较炫的动画效果。
(1)
动态绘制图形:
要动态绘制首先要了解如何动态绘制,比如我们要绘制圆形吧。
实现方式有很多(a)通过自定义View不停调用onDraw()来绘制,开启一个线程,用一个循环while(boolean)每次绘制10度,当等于360度的时候跳出循环。不停的调用invalidate()就可以实现。
(b)也可以使用属性动画来实现。通过开启一个属性动画,设定他的时长,然后根据时长来判断他一定时间需要绘制多少度,然后invalidate(),其实也是通过onDraw()
(c)如果你有很不耐烦的耐性,那你可以把一个园上的点都找出来,然后绘制动态绘制这些点也可以实现,也需要invalidate();
在给控件做动画的时候,我一直都是使用animation的基本动画来给控件界面添加动画,能简单肯定不会用复杂的,我记得在我刚开始的时候要做一个效果,就是要按钮移动然后结束以后固定到结束的点,我记得当时的我是通过给动画添加监听器来判断动画结束的时候,然后让动态设置控件的位置,但是随着对android接触的越来越多,我渐渐的觉得自己当时的方法是相当的笨。
下来就说下objectAnimation跟 ValueAnimation吧:
objectAnimation:
这个子类ValueAnimator支持动画的目标对象上的属性。这类带参数的构造函数定义的目标对象动画以及属性的名称,将动画。然后确定适当的设置/获取函数内部和动画将调用这些函数作为必要的动画属性。
也就是这个动画可以修改view的属性,还能固定他的显示位置,那么就很简单了
ValueAnimation
这个类提供了一个简单的计时引擎运行动画动画计算值和设置在目标对象。
有一个所有动画使用的定时脉冲。它运行在一个自定义处理程序以确保属性更改在UI线程上发生。
默认情况下,ValueAnimator使用非线性插值,通过AccelerateDecelerateInterpolator类,它加速,减慢的动画。这种行为可以改变callingsetInterpolator(TimeInterpolator)。
这个是说动画的所有属性都可以让我们控制,使用更加灵活。
其实学习这个是我在想要画一个抛物线的时候,当我画完了以后我就想抛物线的动画挺好看,然后就研究了下,总结了四种抛物线的动画实现。
(1)
public static int mCount;
/**
* 整个抛物线
* @param imageView
*/
public static void startAnimation(final View view) {
mCount = 300;
Keyframe[] keyframes = new Keyframe[mCount];
final float keyStep = 1f / (float) mCount;
float key = keyStep;
for (int i = 0; i < mCount; ++i) {
keyframes[i] = Keyframe.ofFloat(key, i+ 1);
key += keyStep;
}
PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("translationX", keyframes);
key = keyStep;
for (int i = 0; i < mCount; ++i) {
keyframes[i] = Keyframe.ofFloat(key, -getY(i + 1));
key += keyStep;
}
PropertyValuesHolder pvhY = PropertyValuesHolder.ofKeyframe("translationY", keyframes);
ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(view, pvhY, pvhX).setDuration(3000);
yxBouncer.setInterpolator(new BounceInterpolator());
yxBouncer.start();
}
public static final float a = -1f / 75f;
/**
* 这里是根据三个坐标点{(0,0),(300,0),(150,300)}计算出来的抛物线方程
*
* @param x
* @return
*/
public static float getY(float x) {
if (x>300) {
x= 300;
}
return a * x * x + 4 * x;
}
/**
* 半个抛物线,从上向下
* @param imageView
*/
public static void starthalfAnimation(final View view) {
mCount = 150 ;
Keyframe[] keyframes = new Keyframe[mCount];
final float keyStep = 1f / (float) mCount;
float key = keyStep;
for (int i = 0; i < mCount; ++i) {
keyframes[i] = Keyframe.ofFloat(key, i+ 150);
key += keyStep;
}
PropertyValuesHolder pvhX = PropertyValuesHolder.ofKeyframe("translationX", keyframes);
key = keyStep;
for (int i = 0; i < mCount; ++i) {
keyframes[i] = Keyframe.ofFloat(key, -getY(i + 150));
key += keyStep;
}
PropertyValuesHolder pvhY = PropertyValuesHolder.ofKeyframe("translationY", keyframes);
ObjectAnimator yxBouncer = ObjectAnimator.ofPropertyValuesHolder(view, pvhY, pvhX).setDuration(3000);
yxBouncer.setInterpolator(new BounceInterpolator());
yxBouncer.start();
}
(3)
//也是抛物线
public static void parabolaAnimation(View view){
PropertyValuesHolder holderY = PropertyValuesHolder.ofFloat("translationY", 0.0f,180f);
PropertyValuesHolder holderX = PropertyValuesHolder.ofFloat("translationX", 0.0f,180f);
ObjectAnimator.ofPropertyValuesHolder(view,holderX,holderY).setDuration(2000).start();
}
public static void ParabolaValueAnimation(final View view){
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
/*ViewGroup group = (ViewGroup) view.getParent();
if (group != null) {
group.removeView(view);
}*/
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0, 0));
valueAnimator.setInterpolator(new BounceInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator() {
/**
*
* @param fraction 从0。0 - 1.0
* @param startValue
* @param endValue
* @return
*/
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue) {
PointF pointF= new PointF();
Log.e("point", fraction+"");
pointF.x = 200 * fraction * 3/2;
pointF.y = 0.5f * 200 * (fraction * 3) * (fraction * 3)/2;
return pointF;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF pointF = (PointF)animation.getAnimatedValue();
view.setTranslationX(pointF.x);
view.setTranslationY(pointF.y);
}
});
}
我实验了多种动画,可以看看。
Demo:http://download.csdn.net/detail/u012808234/9095419