带有弹动效果的加载动画实现

项目需求,需要做一个加载动画,如效果图:(demo下载地址https://github.com/gerenvip/TestNineOldAndroid)


主要使用的是属性动画,demo(上面贴出的github地址可以下载)中使用的nineoldAndroid 开源的项目,如果不清楚该项目的可以到github上搜索,或者看一下任玉刚大神的博客 http://blog.csdn.net/singwhatiwanna/article/details/17639987

实现代码:

package com.gerenvip.test.nine;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.AnimatorSet;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.view.ViewHelper;

public class MyActivity extends Activity {

    private ImageView targView1;
    private ImageView targView2;
    private ImageView targView3;
    private int mScreenWith;
    private int mScreenHeight;
    private AnimatorSet set1;
    private AnimatorSet set2;
    private AnimatorSet set3;
    private boolean flag = false;


    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        //获取屏幕的高度
        mScreenHeight = dm.heightPixels;
        //获取屏幕的宽度
        mScreenWith = dm.widthPixels;
        targView1 = (ImageView) findViewById(R.id.iv_i);
        targView2 = (ImageView) findViewById(R.id.iv_u1);
        targView3 = (ImageView) findViewById(R.id.iv_u2);


        //有3个图片,我使用三个AnimatorSet
        set1 = createAnima(targView1);
        set2 = createAnima(targView2);
        set3 = createAnima(targView3);

        //监听第一个animatorset执行情况
        set1.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                //第一个动画执行的时候,是不需要显示后两个动画的,所以,将targView2 targView3隐藏
                targView2.setVisibility(View.INVISIBLE);
                targView3.setVisibility(View.INVISIBLE);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                //flag标记动画是否停止
                if (flag) {
                    //当第一个动画执行完毕,立刻指定第二个动画
                    set2.start();
                }
            }
        });

        set2.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (flag) {
                    //第二个动画执行完毕,执行第三个
                    set3.start();
                }
            }

            @Override
            public void onAnimationStart(Animator animation) {
                //当第二个动画开始的时候为了看到效果,将刚才隐藏的targView2显示出来,这里使用postDelayed的原因是,如果直接setVisibility,会不生效
                targView2.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        targView2.setVisibility(View.VISIBLE);
                    }
                }, 100);
            }
        });

        set3.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                //当三个动画都执行完一遍后,重新开启动画1,如此实现无限循环
                if (flag) {
                    set1.start();
                }
            }

            @Override
            public void onAnimationStart(Animator animation) {
                //第三个动画执行的时候,将targView3 显示可见
                targView3.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        targView3.setVisibility(View.VISIBLE);
                    }
                }, 100);
            }
        });

    }

    /**
     * 创建三个动画集合
     *动画分解为7个步骤:
     * 1.竖直的图片旋转-30度
     * 2.图片下落一个较高的高度
     * 3.弹起
     * 4.在弹起的过程中,将图片旋转到0度,即恢复以前的位置
     * 5.当弹起到顶部的时候,再次下落
     * 6.在下落的过程中,图片旋转到+30度
     * 7.当图片落到底部的时候,在旋转到0度,恢复竖直位置
     * @param targView
     * @return
     */
    private AnimatorSet createAnima(final ImageView targView) {
        final AnimatorSet set = new AnimatorSet();
        //第一次下落比较高的距离
        float longHeight = mScreenHeight * (float) 0.3;
        //弹起的一个比较短的一个距离
        float shortHeight = longHeight - mScreenHeight * (float) 0.1;
        //下落时间
        long downAnimTime = 300;
        long otherTime = 100;
        //顺时针旋转的角度
        float positiveDegree = 30;
        //逆时针旋转角度
        float negativeDegree = -30;


        //初始化动画,时间很短,不需要用户看到,将本来竖直的图片逆时针旋转30度:0 -->-30
        ObjectAnimator initAnim = ObjectAnimator.ofFloat(targView, "rotation", 0, negativeDegree);

        initAnim.setDuration(1);
        initAnim.setInterpolator(new AccelerateInterpolator());

        //图片第一个下落动画
        ObjectAnimator traYdown = ObjectAnimator.ofFloat(targView, "translationY", 0, longHeight);
        traYdown.setDuration(downAnimTime);
        traYdown.setInterpolator(new AccelerateInterpolator());

        //弹起动画
        ObjectAnimator traYUp = ObjectAnimator.ofFloat(targView, "translationY", longHeight, shortHeight);
        traYUp.setInterpolator(new AccelerateInterpolator());
        traYUp.setDuration(otherTime);

        //弹起的过程中,应该执行的旋转为原始位置的动画,-30 -->0
        ObjectAnimator roationz = ObjectAnimator.ofFloat(targView, "rotation", negativeDegree, 0);
        roationz.setDuration(otherTime);
        roationz.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                //设置旋转中心点为图片底部中心点
                ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
                ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
            }
        });

        roationz.setInterpolator(new AccelerateInterpolator());

        //--------------------------------
        //弹起到最高点的时候,开始向右旋转 0 --> 30
        ObjectAnimator roationr = ObjectAnimator.ofFloat(targView, "rotation", 0, positiveDegree);
        roationr.setDuration(otherTime);
        roationr.setInterpolator(new AccelerateInterpolator());
        roationr.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                //设置旋转中心
                ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
                ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
            }
        });

        //第二次下落动画,在下落的过程中执行roationr动画,即下落的同时,向右旋转30度
        ObjectAnimator traYdown2 = ObjectAnimator.ofFloat(targView, "translationY", shortHeight, longHeight);
        traYdown2.setDuration(otherTime);
        traYdown2.setInterpolator(new AccelerateInterpolator());
        //--------------------------------

        //当落下后,执行旋转动画,将图片旋转为竖直位置
        final ObjectAnimator roationz1 = ObjectAnimator.ofFloat(targView, "rotation", positiveDegree, 0);
        roationz1.setDuration(otherTime);
        roationz1.setInterpolator(new AccelerateInterpolator());
        roationz1.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                //设置旋转中心
                ViewHelper.setPivotX(targView, targView.getMeasuredWidth() / 2);
                ViewHelper.setPivotX(targView, targView.getMeasuredHeight());
            }
        });

        //AnimatorSet播放方法有play和playTogether,其中play支持播放单个动画,playTogether支持同时播放多个动画,注意动画之间的时间顺序
        set.play(initAnim).before(traYdown);
        set.play(traYdown).before(traYUp);
        set.playTogether(traYUp, roationz);
        set.play(roationz).before(traYdown2);
        set.playTogether(traYdown2, roationr);
        set.play(roationz1).after(traYdown2);
        return set;
    }

    public void start() {
        set1.start();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        recycleAnim();
    }

    private void recycleAnim() {
        Log.e("WW", "回收资源");
        set1.cancel();
        set2.cancel();
        set3.cancel();
    }

    public void startSecond(View view) {
        Intent intent = new Intent(this, SecondAnimActivity.class);
        startActivity(intent);
    }

    public void startThird(View view) {
        Intent intent = new Intent(this, ThridAnimActivity.class);
        startActivity(intent);
    }

    public void startRecord(View view) {
        Intent intent = new Intent(this, RecordActivity.class);
        startActivity(intent);
    }

    public void rotate(View view) {
        Intent intent = new Intent(this, RotateActivity.class);
        startActivity(intent);
    }

    /**
     * 停止/启动动画
     * @param view
     */
    public void stop(View view) {
        if (flag) {
            recycleAnim();
            flag = false;
        } else {
            start();
            flag = true;
        }
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值