android开发小球回弹动画


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;

import com.example.didi.myproject.R;

public class CustomLoadingView extends View {

    private int leftGlobeColor;
    private int middleGlobeColor;
    private int rightGlobeColor;

    private Paint globePaint;
    private int mCurrentColor;

    public CustomLoadingView(Context context) {
        this(context,null);
    }

    public CustomLoadingView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CustomLoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        leftGlobeColor=ContextCompat.getColor(context,R.color.squareColor);
        rightGlobeColor=ContextCompat.getColor(context,R.color.circleColor);
        middleGlobeColor=ContextCompat.getColor(context,R.color.triangleColor);

        globePaint=new Paint();
        globePaint.setAntiAlias(true);
        globePaint.setStyle(Paint.Style.FILL);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int height=MeasureSpec.getSize(heightMeasureSpec);
        int width=MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(width>height?height:width,width>height?height:width);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawCircle(getWidth()/2,getHeight()/2,getHeight()/2,globePaint);

    }

    public void changeGlobeColor(int globeColor){
        this.mCurrentColor=globeColor;
        globePaint.setColor(globeColor);
        invalidate();

    }


    public int getColor() {
        return this.mCurrentColor;
    }
}

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.RelativeLayout;

public class CustomLoadingViewGroup extends RelativeLayout  {

    private static final int ANIMATION_DURING_TIME =500 ;
    private static int ANIMATION_TRANSLATION_DISTANCE = 0;
    private CustomLoadingView customLoadingView;
    private Context mContext;
    private CustomLoadingView leftGlobe,middleGlobe,rightGlobe;

    public CustomLoadingViewGroup(Context context) {
        this(context,null);
    }

    public CustomLoadingViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CustomLoadingViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        this.mContext=context;
        initLayout(mContext);
    }

    private View getCustomGlobeView(Context context) {
        View view=new CustomLoadingView(context);
        RelativeLayout.LayoutParams params=new RelativeLayout.LayoutParams(dip2px(20),dip2px(20));
        params.addRule(CENTER_IN_PARENT);
        view.setLayoutParams(params);
        return view;
    }


    private void initLayout(Context mContext){
        leftGlobe= (CustomLoadingView) getCustomGlobeView(mContext);
        leftGlobe.changeGlobeColor(Color.RED);

        rightGlobe= (CustomLoadingView) getCustomGlobeView(mContext);
        rightGlobe.changeGlobeColor(Color.BLUE);

        middleGlobe= (CustomLoadingView) getCustomGlobeView(mContext);
        middleGlobe.changeGlobeColor(Color.YELLOW);

        addView(leftGlobe);
        addView(rightGlobe);
        addView(middleGlobe);

        ANIMATION_TRANSLATION_DISTANCE=dip2px(100);
        startOuterAnimation();
    }

    private void startOuterAnimation(){

        ObjectAnimator leftTranslationAnimation=ObjectAnimator.ofFloat(leftGlobe,"translationX",0,-ANIMATION_TRANSLATION_DISTANCE);
        ObjectAnimator rightTranslationAnimation=ObjectAnimator.ofFloat(rightGlobe,"translationX",0,ANIMATION_TRANSLATION_DISTANCE);

        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(ANIMATION_DURING_TIME);
        animatorSet.setInterpolator(new DecelerateInterpolator());
        animatorSet.playTogether(leftTranslationAnimation,rightTranslationAnimation);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                startInnerAnimation();
            }
        });
        animatorSet.start();
    }

    private void startInnerAnimation(){
        ObjectAnimator leftTranslationAnimation=ObjectAnimator.ofFloat(leftGlobe,"translationX",-ANIMATION_TRANSLATION_DISTANCE,0);
        ObjectAnimator rightTranslationAnimation=ObjectAnimator.ofFloat(rightGlobe,"translationX",ANIMATION_TRANSLATION_DISTANCE,0);

        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(ANIMATION_DURING_TIME);
        animatorSet.setInterpolator(new AccelerateInterpolator());
        animatorSet.playTogether(leftTranslationAnimation,rightTranslationAnimation);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {

                int leftColor=leftGlobe.getColor();
                int rightColor=rightGlobe.getColor();
                int middleColor=middleGlobe.getColor();
                leftGlobe.changeGlobeColor(middleColor);
                rightGlobe.changeGlobeColor(leftColor);
                middleGlobe.changeGlobeColor(rightColor);

                startOuterAnimation();
            }
        });
        animatorSet.start();
    }


    private int dip2px(int dip){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
    }

}

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.View;

import com.example.didi.myproject.R;

public class CustomShape extends View {

    private int triangleColor;
    private int squareColor;
    private int circleColor;

    private Paint shapePaint;
    //当前形状
    private Shape mCurrentShape=Shape.Triangle;

    public CustomShape(Context context) {
        this(context,null);
    }

    public CustomShape(Context context,AttributeSet attrs) {
        this(context, attrs,0);
    }

    public CustomShape(Context context,AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        triangleColor=ContextCompat.getColor(context,R.color.triangleColor);
        circleColor=ContextCompat.getColor(context,R.color.circleColor);
        squareColor=ContextCompat.getColor(context,R.color.squareColor);

        shapePaint=new Paint();
        shapePaint.setAntiAlias(true);
        shapePaint.setStyle(Paint.Style.FILL);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width=MeasureSpec.getSize(widthMeasureSpec);
        int height=MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(width>height?height:width,width>height?height:width);

    }

    @Override
    protected void onDraw(Canvas canvas) {

        switch (mCurrentShape){
            case Circle:
                shapePaint.setColor(circleColor);
                canvas.drawCircle(getWidth()/2,getHeight()/2,getHeight()/2,shapePaint);
                break;
            case Square:
                shapePaint.setColor(squareColor);
                Rect rect=new Rect(0,0,getWidth(),getHeight());
                canvas.drawRect(rect,shapePaint);
                break;
            case Triangle:
                shapePaint.setColor(triangleColor);
                Path path=new Path();
                path.moveTo(getHeight()/2,0);
                path.lineTo(0,getHeight());
                path.lineTo(getWidth(),getHeight());
                path.close();
                canvas.drawPath(path,shapePaint);
                break;
        }
    }

    public void exchangeShape(){
        switch (mCurrentShape){
            case Triangle:
                mCurrentShape=Shape.Square;
                break;
            case Square:
                mCurrentShape=Shape.Circle;
                break;
            case Circle:
                mCurrentShape=Shape.Triangle;
                break;
        }
        invalidate();
    }

    public Shape getmCurrentShape() {
        return mCurrentShape;
    }

    enum Shape{

        Circle,
        Triangle,
        Square

    }

}

public class ShapeViewGroup extends LinearLayout {

    private static final int ANIMATION_DURING_TIME = 1000;
    private CustomShape shapeView;
    private View shadowView;
    private boolean isCloseAnimation=false;

    public ShapeViewGroup(Context context) {
        this(context,null);
    }

    public ShapeViewGroup(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ShapeViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initLayout(context);
    }

    private void initLayout(Context context){
        View view=inflate(context, R.layout.shape_layout,this);
        shadowView=view.findViewById(R.id.shadow_view);
        shapeView=view.findViewById(R.id.shape_view);
        //开始动画
        //1,下降动画
        post(new Runnable() {
            @Override
            public void run() {
                startFallAnimation();
            }
        });
    }

    private void startFallAnimation() {

        if (isCloseAnimation){
            return;
        }

        ObjectAnimator fallTranslationYAnimation=ObjectAnimator.ofFloat(shapeView,"translationY",0,dip2px(100));
        ObjectAnimator shadowAnimation=ObjectAnimator.ofFloat(shadowView,"scaleX",1f,0.2f);

        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(ANIMATION_DURING_TIME);
        animatorSet.playTogether(fallTranslationYAnimation,shadowAnimation);
        animatorSet.setInterpolator(new AccelerateInterpolator());//加速插值器
        animatorSet.start();

        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                //在下落结束上升之前切换形状
                shapeView.exchangeShape();
                startUpAnimation();
            }
        });



    }

    private void startUpAnimation(){
        ObjectAnimator upTranslationYAnimation=ObjectAnimator.ofFloat(shapeView,"translationY",dip2px(100),0);
        ObjectAnimator shadowAnimation=ObjectAnimator.ofFloat(shadowView,"scaleX",0.2f,1f);

        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(ANIMATION_DURING_TIME);
        animatorSet.playTogether(upTranslationYAnimation,shadowAnimation);
        animatorSet.setInterpolator(new DecelerateInterpolator());//减速插值器

        animatorSet.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                //在上升动画开始时进行形状旋转
                startRotationAnimation();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                startFallAnimation();
            }

        });
        //这里要注意,必须写在监听动画的后边
        animatorSet.start();

    }
    private void startRotationAnimation() {
        ObjectAnimator rotationAnimator=null;
        switch (shapeView.getmCurrentShape()){
            case Circle:
            case Square:
                rotationAnimator =ObjectAnimator.ofFloat(shapeView,"rotation",0,180);
                break;
            case Triangle:
                rotationAnimator =ObjectAnimator.ofFloat(shapeView,"rotation",0,-120);
                break;
        }
        rotationAnimator.setDuration(ANIMATION_DURING_TIME);
        rotationAnimator.start();
    }

    //怎么让动画暂停,因为如果不把动画停止,他就会一直运行占用资源


    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(VISIBLE);

        shapeView.clearAnimation();
        shadowView.clearAnimation();
        ViewGroup viewGroup= (ViewGroup) this.getParent();
        if (viewGroup!=null){
            viewGroup.removeView(this);
            removeAllViews();
            viewGroup.removeView(shapeView);
        }
        isCloseAnimation=true;

    }

    private int dip2px(int dip){
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,dip,getResources().getDisplayMetrics());
    }

}
发布了75 篇原创文章 · 获赞 31 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/yaoyaoyao_123/article/details/91559585