版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wode_dream/article/details/57409729
Android高级动画所有代码
简介:贝塞尔曲线是计算机图形学中相当重要的参数曲线。可以用数学公式来描述一段曲线。
用途:1、贝塞尔曲线可以帮助我们在二维平面内用平滑的曲线画出各种图形。
2、同时也可以给动画提供一个平滑的曲线运动路径。
android中我们通过Path可以画出二阶跟三阶贝塞尔曲线。复杂的图形我们可以组合几个二阶和三阶的贝塞尔曲线就可以实现。
这次整理一下沿着二阶贝塞尔曲线运动的例子。下面是一个沿着二阶贝塞尔曲线运动的小球的代码和讲解。
示例代码:
1、总共有4个代码文件activity、view、Evalutor和xml文件。
2、先分析下最重要的view文件:
public class TestMove extends View implements View.OnClickListener
{
private float mCircleX,mCircleY; //小球的圆心
private Path mMovePath; //这是用来画贝塞尔曲线的
private Paint mPaintBezier,mPaintCircle; //设置画贝塞尔曲线和园的画笔
private float mStartPointX,mStartPointY; //二阶贝塞尔曲线的起始点
private float mEndPointX,mEndPointY; //二阶贝塞尔曲线的终点
private float mFlagPointX,mFlagPointY; //二阶贝塞尔曲线的支撑点
public TestMove(Context context) {
super(context);
}
public TestMove(Context context, AttributeSet attrs) {
super(context, attrs);
//初始化画笔
mPaintBezier=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintBezier.setStrokeWidth(8);
mPaintBezier.setStyle(Paint.Style.STROKE);
mPaintBezier.setColor(Color.BLUE);
mPaintCircle=new Paint(Paint.ANTI_ALIAS_FLAG);
mPaintCircle.setStrokeWidth(8);
mPaintCircle.setStyle(Paint.Style.FILL_AND_STROKE);
mPaintCircle.setColor(Color.BLUE);
setOnClickListener(this);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
/**
* 系统每一次需要计算大小时都会执行这个方法,比如view改变的时候。所以我们在这里
* 获得起始点、终点和支撑点
*/
mStartPointX = w / 4;
mStartPointY = h / 2 - 200;
mEndPointX = w * 3 / 4;
mEndPointY = h / 2 - 200;
mFlagPointX = w / 2;
mFlagPointY = h / 2 - 400;
mCircleX=mStartPointX;
mCircleY=mStartPointY;
mMovePath=new Path();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//画圆
canvas.drawCircle(mCircleX,mCircleY,30,mPaintCircle);
//给Path设置贝塞尔曲线,然后canvas画
mMovePath.reset();
mMovePath.moveTo(mStartPointX,mStartPointY);
/**
* quadTo()绘制二阶贝塞尔曲线
* cubicTo()绘制三阶贝塞尔曲线
*/
mMovePath.quadTo(mFlagPointX,mFlagPointY,mEndPointX,mEndPointY);
canvas.drawPath(mMovePath,mPaintBezier);
}
@Override
public void onClick(View v) {
PointF flagPoint1=new PointF(mFlagPointX,mFlagPointY);
PointF startPoint=new PointF(mStartPointX,mStartPointY);
PointF endPoint=new PointF(mEndPointX,mEndPointY);
/**
* 在startPoint和endPoint之间运动时返回一个ValueAnimator的值
* MoveEvalutor在它的文件里详细解释
*/
ValueAnimator mValueAnimator=ValueAnimator.ofObject(new MoveEvalutor(flagPoint1),
startPoint,endPoint);
mValueAnimator.setDuration(4000);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
/**
* 把小球的圆心设置到运动点
*/
PointF point=(PointF) animation.getAnimatedValue();
mCircleX=point.x;
mCircleY=point.y;
invalidate();
}
});
mValueAnimator.start();
}
}
3、MoveEvalutor.java的代码:
/**
* Created by zhaofeng on 2017/2/13.
*
* Evalutor允许开发者在任意类型上创建动画,以此来执行动画系统不能直接识别的动画类型。
*/
public class MoveEvalutor implements TypeEvaluator<PointF>{
private PointF mFlagPoint1;
public MoveEvalutor(PointF flagPoint) {
mFlagPoint1=flagPoint;
}
@Override
public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
return CalculateBezierPointForQuadratic(fraction,startValue,mFlagPoint1,endValue);
}
/**
* B(t) = (1 - t)^2 * P0 + 2t * (1 - t) * P1 + t^2 * P2, t ∈ [0,1]
*计算贝塞尔曲线的运动点,这个代码在网上可以找到,二阶的三阶的。
* @param t 曲线长度比例
* @param p0 起始点
* @param p1 控制点
* @param p2 终止点
* @return t对应的点
*/
public static PointF CalculateBezierPointForQuadratic(float t, PointF p0, PointF p1, PointF p2) {
PointF point = new PointF();
float temp = 1 - t;
point.x = temp * temp * p0.x + 2 * t * temp * p1.x + t * t * p2.x;
point.y = temp * temp * p0.y + 2 * t * temp * p1.y + t * t * p2.y;
return point;
}
}
4、在activity_move_on_bezier.xml,在xml文件中引入view文件。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_move_on_bezier"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.zfeng.bazier.MoveOnBezierActivity">
<com.zfeng.bazier.view.MoveOnBezierView
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
5、在activity中执行:
public class MoveOnBezierActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_move_on_bezier);
}
}
以上就是全部的代码,点击view,小球就会沿着二阶贝塞尔曲线运动。
参考资料:
https://developer.android.com/reference/android/view/View.html
https://developer.android.com/reference/android/graphics/Path.html
https://developer.android.com/reference/android/animation/ValueAnimator.html
https://developer.android.com/reference/android/animation/TypeEvaluator.html