Android四十二章经之-动画-

View动画(补间动画):平移translate,旋转rotate,缩放scale,透明度alpha!
帧动画:通过切换一组图片,来达到动画的效果!
属性动画:通过动态的改变对象的属性,来实现动画效果!

1、view动画,首先view动画的使用是通过xml文件定义一些上面提到的四种属性,来进行操作的!
view动画可以是一个动画,也可以是一组动画的集合,集合使用set标签;
set有两个属性,分别是顺序执行,和一起执行
android:ordering=”sequentially”
android:ordering=”together”

<set xmlns:android="http://schemas.android.com/apk/res/android"
    >
    <!-- 在水平和垂直方向完成动画效果,属性分别为,起始坐标,和结束坐标-->
    <!-- fillAfter 属性为动画播放完毕之后是否停留在结束位置,TRUE表示留在此位置-->
    <!-- repeatMode 属性为动画播放完毕之后播放模式,reverse 表示反方向播放、restart表示重新正方向执行-->
    <!-- 属性:interpolator 指定一个动画的插入器
       由系统提供,常见动画插入器:
            accelerate_decelerate_interpolator  加速-减速 动画插入器
            accelerate_interpolator        加速-动画插入器
            decelerate_interpolator        减速- 动画插入器
            anticipate_interpolator 先回退一小步然后加速前进
            anticipate_overshoot_interpolator   在上一个基础上超出终点一小步再回到终点
            bounce_interpolator 最后阶段弹球效果
            cycle_interpolator  周期运动
            linear_interpolator 匀速
            overshoot_interpolator  快速到达终点并超出一小步最后回到终点-->
    <translate
        android:fillAfter="false"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="100"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:repeatMode="reverse"
        android:toYDelta="100"/>
    <!-- 起始角度和结束角度,轴心坐标 其中轴心坐标可以是50%(表示view的X或者Y的中间)-->
    <!-- repeatCount表示重复播放次数,-1表示持续播放-->
    <rotate
        android:fromDegrees="0"
        android:pivotX="100"
        android:repeatCount="-1"
        android:pivotY="100"
        android:toDegrees="360"
        />
    <!-- 分别是水平和垂直的起始缩放值与结束值,轴心坐标-->
    <scale
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:pivotX="100"
        android:pivotY="100"
        android:toXScale="1.2"
        android:toYScale="1.2"/>
    <!-- 透明度的起始值和缩放值-->
    <alpha
        android:fromAlpha="0.1"
        android:toAlpha="1"/>
</set>

像我这样使用它:

 textView = (TextView) findViewById(R.id.textview);
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.test_anima);
        animation.setDuration(2000);//这句话的意思是,这个动画持续两秒钟,不然默认值太短了不方便观察效果 ^_^
        textView.startAnimation(animation);

自定义动画:
子类只要继承Animation抽象类即可!
在initialize中初始化一些东西,在applyTransformation中变换矩阵
用法与上面的一致只是得到对象的时候,不是利用animationutils而是直接new出来,并在构造方法中初始化:

MyAnimator animator = new MyAnimator(0,360,120,100,-1220,true,new Camera());
    animator.setDuration(2000);
    textView.startAnimation(animator);

自定义Animation:

public class MyAnimator extends Animation {
    private final float mFromDegrees;
    private final float mToDegrees;
    private final float mCenterX;
    private final float mCenterY;
    private final float mDepthZ;
    private final boolean mReverse;
    private Camera mCamera;

    public MyAnimator(float mFromDegrees, float mToDegrees, float mCenterX, float mCenterY, float
            mDepthZ, boolean mReverse, Camera camera) {
        this.mFromDegrees = mFromDegrees;
        this.mToDegrees = mToDegrees;
        this.mCenterX = mCenterX;
        this.mCenterY = mCenterY;
        this.mDepthZ = mDepthZ;
        this.mReverse = mReverse;

    }

    @Override
    public void initialize(int width, int height, int parentWidth, int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
        mCamera = new Camera();
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t){//apply:申请,Transformation:转化
        final float formDegrees = mFromDegrees;

        final float degrees = formDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
        final float cx = mCenterX;
        final float cy = mCenterY;
        final Camera c = mCamera;

        final Matrix matrix = t.getMatrix();
        c.save();

        if (mReverse) {
            c.translate(0, 0, mDepthZ * interpolatedTime);
        } else {
            c.translate(0, 0, mDepthZ * (1.0f - interpolatedTime));
        }

        c.rotateY(degrees);
        c.getMatrix(matrix);
        c.restore();

        matrix.preTranslate(-cx,-cy);
        matrix.postTranslate(cx,cy);
    }
}

这里写图片描述

帧动画:
帧动画就是一系列图片的顺序播放;
其中在xml文件中应该 这样写:

这么定义的!
 private AnimationDrawable t1_icon1_animationDrawable;
 private ImageView t1_icon1;
  //这是一个帧动画 animation-list 这样使用
                t1_icon1.setImageResource(R.drawable.t1_frame_animation);
                t1_icon1_animationDrawable = (AnimationDrawable) t1_icon1.getDrawable();
                t1_icon1_animationDrawable.start();
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >
<!--   
    根标签为animation-list,其中oneshot代表着是否只展示一遍,设置为false会不停的循环播放动画  
    根标签下,通过item标签对动画中的每一个图片进行声明  
    android:duration 表示展示所用的该图片的时间长度  
 -->  
    <item
        android:drawable="@mipmap/tutorial1_icon1"
        android:duration="200"/>
    <item
        android:drawable="@mipmap/tutorial1_icon2"
        android:duration="200"/>

</animation-list>

属性动画:
动画默认时间间隔300ms,默认帧率10ms/帧
最常用的几个属性动画类:ValueAnimator、ObjectAnimator、AnimatorSet;
其中ObjectAnimator继承自ValueAnimator;

通过属性动画改编一个对象的背景颜色:

 ValueAnimator animator = ObjectAnimator.ofInt(textView,"backgroundColor",/*Red*/0xFFFF8080,/*Blue*/0xFF8080FF);
                animator.setDuration(3000);//持续时间
                animator.setEvaluator(new ArgbEvaluator());
                animator.setRepeatCount(ValueAnimator.INFINITE);//无限播放,普及一个单词indefinitely无限的意思
                animator.setRepeatMode(ValueAnimator.REVERSE);//逆过来播放
                animator.start();

image

动画集合:注释写的明明白白^_* 可以逐条注释掉,然后试试就明白了

AnimatorSet animatorSet = new AnimatorSet();
                animatorSet.playTogether(
                        ObjectAnimator.ofFloat(textView,"rotationX", 0, 90 * 4),//x轴旋转一周
                        ObjectAnimator.ofFloat(textView, "rotationY", 0, 90 * 4),//y轴旋转一周,此时他两个混合在一起很不好思考究竟为什么会是这个造型!嘤嘤
                        ObjectAnimator.ofFloat(textView, "rotation", 0, 90*4),//z轴旋转一周(xyz的坐标轴就是普通的三维坐标轴,上面是y,右面是x,前面是z!^_^),此时他们三个一起旋转已经是很玄学了
                        ObjectAnimator.ofFloat(textView, "translationX", 0, 90),//x轴平移
                        ObjectAnimator.ofFloat(textView, "translationY", 0, 90),//y轴平移,平移没有z轴了!呦桑
                        ObjectAnimator.ofFloat(textView, "scaleX", 1, 2,1),//x缩放
                        ObjectAnimator.ofFloat(textView, "scaleY", 1, 0.1f,1),//y缩放
                        ObjectAnimator.ofFloat(textView, "alpha", 1, 0.25f, 1));//透明度1~0.25~1);
                animatorSet.setDuration(5 * 1000);
                animatorSet.start();

image

属性动画集合如果想要设置repeat等属性,定义出对象来,之后添加到set集合中去,因为repeat返回的是void,所以像上面写的匿名类写法不能实现。

属性动画当然也可以写到xml文件中去:写法与上面的view动画set相似,只不过是把子节点的名字改为属性动画的节点名字而已!

<objectAnimator android:propertyName="" android:duration="" android:repeatCount="" android:repeatMode="" android:valueFrom="" android:valueTo=""等!

以后或许会用到这个:
实现一个翻转到背面!再翻转回来的效果:关于属性动画,就是按照下面的方法,还是蛮简单的!就不介绍了(其实我真的介绍不明白)

image

大体思路就是两个view重叠,正面的显示,背面的不显示,然后利用动画正面从0°翻转到90°之后不显示,反面显示,反面从-90°到0°。以我的脑回路复杂程度来讲,理解这些需要。。。。不说了。
后来想了想,发现已经到90°了就已经看不见了,就不写alpha了哈!

下面是代码:

public class AnimationActivity extends AppCompatActivity implements View.OnClickListener {
    private TextView tv1, tv2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_animation2);
        tv1 = (TextView) findViewById(R.id.tv1);
        tv2 = (TextView) findViewById(R.id.tv2);
        tv1.setOnClickListener(this);
        tv2.setOnClickListener(this);
    }
    private boolean isFront = true;
    @Override
    public void onClick(View v) {
        flip();
    }
    private void flip() {
        if (isFront) {
            flipAnination(tv1,tv2);
        }else{
            flipAnination(tv2,tv1);
        }
    }
    private void flipAnination(View view1,final View view2) {
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(view1, "rotationY", 0, 90).setDuration(2000);
        animator1.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                tv2.setClickable(false);
                tv1.setClickable(false);
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                tv2.setClickable(true);
                tv1.setClickable(true);
            }
            @Override
            public void onAnimationCancel(Animator animation) {
            }
            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        animator1.start();//监听事件一定要写在start前面,否则,,,哼!。。。
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(view2, "rotationY", -90, 0).setDuration(2000);
        animator2.setStartDelay(2000);
        animator2.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                tv2.setClickable(false);
                tv1.setClickable(false);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                tv2.setClickable(true);
                tv1.setClickable(true);
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
        animator2.start();
        isFront = !isFront;
    }
}

这里是xml代码:加了一个旋转90°,就看不见了呢! < ^_^ > !

 <TextView
        android:id="@+id/tv1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:rotationY="90"
        android:text="你好 世界!"   
        />

写的不好!谁有更好的告诉我一下哟!

学ぼうと
Manabou to

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值