1. 程式人生 > >關於ValueAnimation以及Interpolator +Drawable實現的自己定義動畫效果

關於ValueAnimation以及Interpolator +Drawable實現的自己定義動畫效果

idt edit 由於 height over 等等 -s line alt

ValueAnimation :

Android中的屬性動畫,他跟objectAnimation是比補間動畫擁有更強大的功能,能夠操作對象。所以我們能夠在自 定義View中通過他們來實現些特別的功能。

Interpolator:?

插值器,通過插值器我們能實現比方反彈。重力加速度。等等的效果。

Android本來就自帶了插值器。加速減速等等。並且在最新的v4包中還加入了幾個新的插值器,能夠上網搜下,看看不同的插值器的效果。

Drawable :Drawable這個類是能夠用來繪制的類


通過自己定義Drawable 能夠實現非常多不通過的功能:

技術分享圖片

由於不是動態圖片。看不到實際效果。能夠下載Demo自己執行下看看。


關於自己定義Drawable 的步驟:


1、用一個類繼承Drawable

2、創建一個ValueAnimator 對象。設置他的各種屬性以及加入AnimatorUpdateListener。然後通過他的監聽器能夠設置你控件的動畫效果

3、創建一個畫筆,用來進行繪制你所要繪制的東西

4、繪制的時候按你的需求來計算要繪制的東西(功能不一樣計算方式也不一樣)


看上圖第一個控件的實現方式:

package com.example.modifyprogress;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.view.animation.Animation;
import app.dinus.com.loadingdrawable.MaterInterpolator;


@SuppressLint("NewApi")
public class LoadingDrawable extends Drawable{
    private Drawable mDrawable;
    private Path mPath = new Path();
    private float mPercent;
    private ValueAnimator mAnimator;
    public LoadingDrawable(Drawable drawable) {
        this.mDrawable = drawable;
      
        mAnimator = ValueAnimator.ofFloat(0.0f,1.0f);
        mAnimator.setDuration(5000);
        mAnimator.setRepeatCount(Animation.INFINITE);
        mAnimator.setRepeatMode(Animation.REVERSE);
        mAnimator.setInterpolator(MaterInterpolator.createInterpolator().setDefault_Type(MaterInterpolator.BOUNCE));
        mAnimator.addUpdateListener(new AnimatorUpdateListener() {
			
			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				
				if (mPercent < 1) {
					mPercent += (Float)animation.getAnimatedValue()/100;
	            } else {
	            	mPercent = 0;
	            }
	           invalidateSelf();
			}
		});
        mAnimator.start();
    }
    @Override
    public void draw(Canvas canvas) {
        mPath.reset();
        RectF rect = new RectF(getBounds());
        double radius = Math.pow(Math.pow(rect.right, 2) + Math.pow(rect.bottom, 2), 0.5);
        mPath.moveTo(rect.right / 2, rect.bottom / 2);
        mPath.lineTo(rect.right / 2, 0);
        if (mPercent > 0.125f) {
            mPath.lineTo(rect.right, 0);
        }
        if (mPercent > 0.375f) {
            mPath.lineTo(rect.right, rect.bottom);
        }
        if (mPercent > 0.625f) {
            mPath.lineTo(0, rect.bottom);
        }
        if (mPercent > 0.875f) {
            mPath.lineTo(0, 0);
        }
        mPath.lineTo((float) (rect.right / 2 + radius * Math.sin(Math.PI * 2 * mPercent)),
                (float) (rect.bottom / 2 - radius * Math.cos(Math.PI * 2 * mPercent)));
        mPath.close();
        if (mPercent >= 0 && mPercent <= 1) {
            canvas.save();
            canvas.clipPath(mPath);
            mDrawable.draw(canvas);
            canvas.restore();
        }
    }

    @Override
    public void setAlpha(int alpha) {
        mDrawable.setAlpha(alpha);
    }

    @Override
    public int getAlpha() {
        return mDrawable.getAlpha();
    }

    @Override
    public void setColorFilter(ColorFilter cf) {
        mDrawable.setColorFilter(cf);
    }


    @Override
    public int getOpacity() {
        // TODO Auto-generated method stub
        return mDrawable.getOpacity();
    }

  

    @Override
    protected void onBoundsChange(Rect bounds) {
        mDrawable.setBounds(bounds);
    }

    @Override
    public int getIntrinsicHeight() {
        return mDrawable.getIntrinsicHeight();
    }

    @Override
    public int getIntrinsicWidth() {
        return mDrawable.getIntrinsicWidth();
    }


    public void setPercent(float percent) {
        if (percent > 1) {
            percent = 1;
        } else if (percent < 0) {
            percent = 0;
        }
        if (percent != mPercent) {
            this.mPercent = percent;
            invalidateSelf();
        }
    }

}


我自己自己定義了幾個插值動畫。關於插值動畫的測試能夠在:http://inloop.github.io/interpolator/

package app.dinus.com.loadingdrawable;


import android.view.animation.Interpolator;
/**
 *各種插值器效果
 * @author chenpengfei_d
 *能夠去這個網址上看效果: http://inloop.github.io/interpolator/
 */
public class MaterInterpolator implements Interpolator{
	private int mDefault_Type = LINEAR;
	private float interpolatorValue;
	private static MaterInterpolator mInterpolator;
	public static  MaterInterpolator createInterpolator(){
		if (mInterpolator == null) {
			mInterpolator = new MaterInterpolator();
		}
		return mInterpolator;
	}
	
	@Override
	public float getInterpolation(float input) {
		
		switch (mDefault_Type) {
		case LINEAR: //線性
			interpolatorValue = input;
			break;
		case ACCELERATE: //加速
			float factor = 1.0f;
			if (factor == 1.0) {
				factor = input * input;
			}else {
				factor = (float)Math.pow(input, factor *2);
			}
			interpolatorValue = factor;
			break;
		case ACCELERATEDECELERATE://先加速後減速
			interpolatorValue = (float) ((Math.cos((input + 1) * Math.PI) /2.0) + 0.5F);
			break;
		case ANTICIPATE: 
			
			float tension = 2.0f;
			interpolatorValue = input * input *((tension + 1) * input - tension);
			break;
		case ANTICIPATEOVERSHOOT:
			tension = 2.0f * 1.5f;
			if (input < 0.5){
				interpolatorValue = (float) (0.5 * (Math.pow(input * 2.0f, 2) * ((tension + 1) * input  - tension)));
			}else {
				interpolatorValue = (float) (0.5 *(Math.pow(((input - 1) * 2.0f), 2) *((tension  + 1) *(input - 1) * 2.0f + tension)));
			}
			break;
		case BOUNCE://反彈
			if (input < 0.3535) {
				interpolatorValue =	bounce(input);
			}else if(input < 0.7408){
				interpolatorValue = bounce(input - 0.54719f) + 0.7f;
			}else if (input < 0.9644) {
				interpolatorValue = bounce(input - 0.8526f) + 0.9f;	
			}else {
				interpolatorValue = bounce(input - 1.0435f) + 0.95f;  
			}
			break;
		case CUBICHERMITE:
			interpolatorValue = CubicHermite(input, 0, 1, 4, 4);
			break;
		case CYCLE:
			float cycles = 1.0f;
			interpolatorValue = (float)Math.sin(2* cycles *Math.PI *input);
			break;
		case DECELERATE://減速
			float divisor = 1.0f;
			if (divisor == 1.0) {
				interpolatorValue = (float) (1.0 - (1.0 - input ) * (1.0 - input));
			}else {
				interpolatorValue = (float) (1.0 - Math.pow((1.0 - input), 2 * divisor));
			}
			break;
		case OVERSHOOT:
			tension = 2.0f;
			input = input - 1.0f;
			interpolatorValue = (float) (input *input *((tension  + 1) * input  + tension ) +1.0);
			break;
		case SMOOTHSTEP:
			interpolatorValue = input * input * (3 - 2 *input );
			break;
		case SPRING://彈簧效果
			factor = 0.4f;
			interpolatorValue = (float) (Math.pow(2,  -10 *input) * Math.sin((input - factor /4) *(2 *Math.PI)/factor ) + 1.0);
			break;
		default:
			break;
		}
		
		
		return  interpolatorValue;
	}


	private float bounce(float input){	
		return input *input *8;
	}
	private float CubicHermite(float t, int p0,int p1,int m0,int m1){
		float t2 = t* t;
		float t3 = t2 * t ;
		return  (2* t3 - 3 * t2 +1) * p0 + (t3 - 2 * t2 + t) * m0 + (-2 * t3 + 3 * t2) * p1 + (t3 - t2) *m1;
	}
	public int getDefault_Type() {
		return mDefault_Type;
	}
	public MaterInterpolator setDefault_Type(int default_Type) {
		mDefault_Type = default_Type;
		return mInterpolator;
	}
	public static final int LINEAR =0 ;
	public static final int SMOOTHSTEP = 1;
	public static final int ACCELERATEDECELERATE = 2;
	public static final int BOUNCE = 3;
	public static final int ACCELERATE = 4;
	public static final int ANTICIPATEOVERSHOOT = 5;
	public static final int CYCLE = 6;
	public static final int ANTICIPATE = 7;
	public static final int DECELERATE = 8;
	public static final int OVERSHOOT = 9;
	public static final int CUBICHERMITE = 10;
	public static final int SPRING = 11;
	public  enum MaterInterPolatorType{
		LINEAR,SMOOTHSTEP,SPRING,CUBICHERMITE,OVERSHOOT,DECELERATE,ANTICIPATE,CYCLE,ANTICIPATEOVERSHOOT
		,ACCELERATE,BOUNCE,ACCELERATEDECELERATE
	}
}


還有其它的效果能夠看代碼裏邊。下載執行就好,效果還不錯,個人感覺。


Demo:http://download.csdn.net/detail/u012808234/9498353




關於ValueAnimation以及Interpolator +Drawable實現的自己定義動畫效果