自定义ValueAnimator的TypeEvaluator
翻译过来就是类型计算器,对,就是一个计算器,只不过这计算器的计算规则由你设定,也就是你要继承重写喽。
对于valueAnimator类中的其他ofXXx方法,其实都是有计算器,默认好像是FloatEvaluator的。
本文这次改变属性是一个点的x,y跟随要给曲线运动动画效果:
妈的,这 gif录制工具太差了,变成绿低了。但是还是能看出小蝌蚪在动。
下面看代码:
activity的布局文件就一个imageview,等会这个就是存放你的运动点的容器。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv"
android:layout_width="300dp"
android:layout_height="400px"
android:layout_margin="50dp"/>
</LinearLayout>
activity代码
这里是根据imageview的尺寸 去设置起点和终点的。
有个iamgeview尺寸的获取,利用视图树,当iamgeview绘制好了,再去获取其宽高。
自定义了一个pointDrawable,和myself类下面有代码
package com.example.zxq.bsquxian;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import com.example.zxq.bsquxian.zidiyizhidonghua.MySelf;
import com.example.zxq.bsquxian.zidiyizhidonghua.Point;
import com.example.zxq.bsquxian.zidiyizhidonghua.PointDrawable;
/**
* Created by Administrator on 2017/7/26 0026.
*/
public class ShuxingAnmationActivity extends AppCompatActivity {
private ImageView iv;
private int width;
private int height;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shuxingdonghua);
iv= (ImageView) findViewById(R.id.iv);
int intw=View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int inth=View.MeasureSpec.makeMeasureSpec(0,View.MeasureSpec.UNSPECIFIED);
iv.measure(intw, inth);
iv.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
height = iv.getHeight();
width = iv.getWidth();
iv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
final PointDrawable pointDrawable=new PointDrawable(width,height);
iv.setBackground(pointDrawable);
ValueAnimator valueAnimator = ValueAnimator.ofObject(new MySelf(), pointDrawable.getStartPoint(), pointDrawable.getEndPoint());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Point animatedValue = (Point) valueAnimator.getAnimatedValue();
pointDrawable.setCurrentPoint(animatedValue);
pointDrawable.invalidateSelf();
}
});
valueAnimator.setDuration(5000);
valueAnimator.setInterpolator(new LinearInterpolator());//设置插值器
valueAnimator.start();
}
});
}
}
pointDrawable的代码:
创建这个对象的时候,创建了两个点,起点和终点,还有画笔
在draw()方法中去绘制图形
在setcurrentpoint()方法中,当前运动点的位置传进来。这个方法是在activity中动画运行监听中调用的。在上面
package com.example.zxq.bsquxian.zidiyizhidonghua;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PictureDrawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2017/7/26 0026.
*/
public class PointDrawable extends Drawable {
private Point startPoint;
private Point endPoint;
private Point currentPoint;
private final Paint paint;
private List<Point> list=new ArrayList<Point>();
public void setCurrentPoint(Point currentPoint) {
this.currentPoint = currentPoint;
}
public void setStartPoint(Point startPoint) {
this.startPoint = startPoint;
}
public void setEndPoint(Point endPoint) {
this.endPoint = endPoint;
}
public Point getStartPoint() {
return startPoint;
}
public Point getEndPoint() {
return endPoint;
}
public PointDrawable(int width,int height){
startPoint = new Point(0,height/2);
endPoint = new Point(width,height/2);
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawColor(Color.BLACK);
if(currentPoint!=null)
{
Log.e("jinlai",currentPoint.getX()+"???"+currentPoint.getY());
if(list.size()<20)
{
list.add(currentPoint);
}else{
list.remove(0);
list.add(currentPoint);
}
for (int i=0;i<list.size();i++)
{
Point point = list.get(i);
int r=i/2;
canvas.drawCircle(point.getX(),point.getY(),r,paint);
}
}
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int i) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return 1;
}
}
MySelf类就是真个点运动位置的计算方法
实现TypeEvaluator接口
方法中的那两个点就是activity代码中的创建动画传进来的开始和结束点,x成线性变化,y成正玄曲线变化。
package com.example.zxq.bsquxian.zidiyizhidonghua;
import android.animation.TypeEvaluator;
import android.widget.Button;
/**
* Created by Administrator on 2017/7/26 0026.
*/
public class MySelf implements TypeEvaluator<Point> {
@Override
public Point evaluate(float v, Point point, Point t1) {
int x = (int) (v*(t1.getX()-point.getX()));
int y = (int) (50 * (float) (Math.sin(0.01 * Math.PI * x)) +200);
return new Point(x,y);
}
}
这就是整个过程。主要用途就是根据自己的计算规则实现动态计算,获取要的数据,然后在