package com.marshalchen.common.uimodule.timelytextview;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;
import com.marshalchen.common.uimodule.timelytextview.animation.TimelyEvaluator;
import com.marshalchen.common.uimodule.timelytextview.model.NumberUtils;
import com.nineoldandroids.animation.ObjectAnimator;
import com.nineoldandroids.util.Property;
public class TimelyView extends View {
private static final float RATIO = 1f;
private static final Property<TimelyView, float[][]> CONTROL_POINTS_PROPERTY = new Property<TimelyView, float[][]>(float[][].class, "controlPoints") {
@Override
public float[][] get(TimelyView object) {
return object.getControlPoints();
}
@Override
public void set(TimelyView object, float[][] value) {
object.setControlPoints(value);
}
};
private Paint mPaint = null;
private Path mPath = null;
private float[][] controlPoints = null;
public TimelyView(Context context) {
super(context);
init();
}
public TimelyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TimelyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
public float[][] getControlPoints() {
return controlPoints;
}
public void setControlPoints(float[][] controlPoints) {
this.controlPoints = controlPoints;
invalidate();
}
public ObjectAnimator animate(int start, int end) {
float[][] startPoints = NumberUtils.getControlPointsFor(start);
float[][] endPoints = NumberUtils.getControlPointsFor(end);
return ObjectAnimator.ofObject(this, CONTROL_POINTS_PROPERTY, new TimelyEvaluator(), startPoints, endPoints);
}
public ObjectAnimator animate(int end) {
float[][] startPoints = NumberUtils.getControlPointsFor(-1);
float[][] endPoints = NumberUtils.getControlPointsFor(end);
return ObjectAnimator.ofObject(this, CONTROL_POINTS_PROPERTY, new TimelyEvaluator(), startPoints, endPoints);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (controlPoints == null) return;
int length = controlPoints.length;
int height = getMeasuredHeight();
int width = getMeasuredWidth();
float minDimen = height > width ? width : height;
mPath.reset();
mPath.moveTo(minDimen * controlPoints[0][0], minDimen * controlPoints[0][1]);
for (int i = 1; i < length; i += 3) {
mPath.cubicTo(minDimen * controlPoints[i][0], minDimen * controlPoints[i][1],
minDimen * controlPoints[i + 1][0], minDimen * controlPoints[i + 1][1],
minDimen * controlPoints[i + 2][0], minDimen * controlPoints[i + 2][1]);
}
canvas.drawPath(mPath, mPaint);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
int height = getMeasuredHeight();
int widthWithoutPadding = width - getPaddingLeft() - getPaddingRight();
int heigthWithoutPadding = height - getPaddingTop() - getPaddingBottom();
int maxWidth = (int) (heigthWithoutPadding * RATIO);
int maxHeight = (int) (widthWithoutPadding / RATIO);
if (widthWithoutPadding > maxWidth) {
width = maxWidth + getPaddingLeft() + getPaddingRight();
} else {
height = maxHeight + getPaddingTop() + getPaddingBottom();
}
setMeasuredDimension(width, height);
}
private void init() {
// A new paint with the style as stroke.
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(5.0f);
mPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
}
}