Android之动画

一直对画画相关不感冒,但是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.定义动画文件

Android之动画_第1张图片
gitHub上有一个使用SVG 的很好的例子,我就是参考的这个:https://gist.github.com/nickbutcher/b3962f0d14913e9746f2,作者少传里几个文件,我修改了一下,代码里添加了一些注释,原作者的成果,效果就是上面的图里的效果,有需要的可以下载源码。

最后是一个下拉动画,使用的是ValueAnimator,使用其产生一定具有规律的数字来实现淡出和淡入效果



附件:源码:https://github.com/CL-window/animations

你可能感兴趣的:(动画)