博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于ValueAnimation以及Interpolator +Drawable实现的自己定义动画效果
阅读量:6091 次
发布时间:2019-06-20

本文共 7718 字,大约阅读时间需要 25 分钟。

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();        }    }}

我自己自己定义了几个插值动画。关于插值动画的測试能够在:

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:

你可能感兴趣的文章
Oracle DG 逻辑Standby数据同步性能优化
查看>>
exchange 2010 队列删除
查看>>
「翻译」逐步替换Sass
查看>>
H5实现全屏与F11全屏
查看>>
处理excel表的列
查看>>
C#数据采集类
查看>>
quicksort
查看>>
【BZOJ2019】nim
查看>>
LINUX内核调试过程
查看>>
【HDOJ】3553 Just a String
查看>>
Java 集合深入理解(7):ArrayList
查看>>
2019年春季学期第四周作业
查看>>
linux环境配置
查看>>
tomcat指定配置文件路径方法
查看>>
linux下查看各硬件型号
查看>>
epoll的lt和et模式的实验
查看>>
Flux OOM实例
查看>>
07-k8s-dns
查看>>
Android 中 ListView 分页加载数据
查看>>
oracle启动报错:ORA-00845: MEMORY_TARGET not supported on this system
查看>>