關於ValueAnimation以及Interpolator +Drawable實現的自己定義動畫效果
阿新 • • 發佈:2018-02-14
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實現的自己定義動畫效果