package com.walking.strong.widget;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import com.money.common.ComponentContext;
import com.money.common.log.DLog;
import com.money.statistics.StatisticsUtils;
import com.walking.strong.R;
import com.walking.strong.bean.WalkStepTipsBean;
import com.walking.strong.bean.response.ConfigResponse;
import com.walking.strong.constant.StatisticConstants;
import com.walking.strong.mvp.model.IUserInfoModel;
import com.walking.strong.utils.GoldUtils;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class DashboardPointView extends View {
private int mRadius;
private int mStartAngle = 150;
private int mSweepAngle = 240;
private int mMin = 0;
private int mMax = 6000;
private int mSection = 4;
private double mPortion = 15;
private String mHeaderText = "今日步数";
private String mTips = "";
private int mStrokeWidth;
private int mLength1;
private int mLength2;
private int mStepCount = 1500;
private int goldCoin = 0;
private int mStepRecord;
private boolean mRefreshText = true;
private int mPadding;
private float mCenterX, mCenterY;
private Paint mPaint;
private Paint mTextPaint;
private Paint mProgressPaint;
private Rect mRectText;
private String[] mTexts;
private ValueAnimator mValueAnimator;
public DashboardPointView(Context context) {
this(context, null);
}
public DashboardPointView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public DashboardPointView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mStrokeWidth = dp2px(3);
mLength1 = dp2px(13) + mStrokeWidth;
mLength2 = mLength1 + dp2px(4);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mStrokeWidth);
mPaint.setColor(ContextCompat.getColor(getContext(), R.color.color_FFC801));
mProgressPaint = new Paint();
mProgressPaint.setAntiAlias(true);
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
mProgressPaint.setStyle(Paint.Style.STROKE);
mProgressPaint.setStrokeWidth(mStrokeWidth);
mProgressPaint.setColor(ContextCompat.getColor(getContext(), R.color.color_progress));
mTextPaint = new Paint();
mProgressPaint.setAntiAlias(true);
mProgressPaint.setStrokeCap(Paint.Cap.ROUND);
mProgressPaint.setStrokeWidth(mStrokeWidth);
mTextPaint.setTextSize(sp2px(12));
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaint.setColor(ContextCompat.getColor(getContext(), R.color.scale_text_color));
Typeface dincond_bold = Typeface.createFromAsset(ComponentContext.getContext().getAssets(), "fonts/DINCond-Bold.otf");
mTextPaint.setTypeface(dincond_bold);
mRectText = new Rect();
mTexts = new String[mSection + 1];
for (int i = 0; i < mTexts.length; i++) {
if (i == 0) {
mTexts[i] = "1";
} else {
int n = (mMax - mMin) / mSection;
mTexts[i] = String.valueOf(mMin + i * n);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mPadding = Math.max(
Math.max(getPaddingLeft(), getPaddingTop()),
Math.max(getPaddingRight(), getPaddingBottom())
);
setPadding(mPadding, mPadding, mPadding, mPadding);
int width = resolveSize(dp2px(245), widthMeasureSpec);
mRadius = (width - mPadding * 2 - mStrokeWidth * 2) / 2;
setMeasuredDimension(width, width - dp2px(50));
mCenterX = mCenterY = getMeasuredWidth() / 2f;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(ContextCompat.getColor(getContext(), R.color.transparent));
drawScale(canvas);
drawScaleProgress(canvas);
drawHeadText(canvas);
drawStepCount(canvas);
}
private void drawScale(Canvas canvas) {
canvas.save();
mPaint.setStrokeWidth(mStrokeWidth);
mPaint.setColor(ContextCompat.getColor(getContext(), R.color.dashboard_scale_gray));
double cos = Math.cos(Math.toRadians(mStartAngle - 180));
double sin = Math.sin(Math.toRadians(mStartAngle - 180));
float x0 = (float) (mPadding + mStrokeWidth + mLength1 / 3 + (mRadius - mLength1 / 3) * (1 - cos));
float y0 = (float) (mPadding + mStrokeWidth + mLength1 / 3 + (mRadius - mLength1 / 3) * (1 - sin));
float x2 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * cos);
float y2 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * sin);
float lx0 = (float) (mPadding + mStrokeWidth + mRadius * (1 - cos));
float ly0 = (float) (mPadding + mStrokeWidth + mRadius * (1 - sin));
float lx1 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * cos);
float ly1 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * sin);
float angle = (float) (mSweepAngle * 1f / (mSection * mPortion));
for (int i = 0; i <= mSection * mPortion; i++) {
if (i % mPortion == 0) {
mPaint.setStrokeWidth(mStrokeWidth);
canvas.drawLine(lx0, ly0, lx1, ly1, mPaint);
} else {
canvas.drawLine(x0, y0, x2, y2, mPaint);
}
canvas.rotate(angle, mCenterX, mCenterY);
}
canvas.restore();
}
private void drawScaleProgress(Canvas canvas) {
canvas.save();
mProgressPaint.setStrokeWidth(mStrokeWidth);
double cos = Math.cos(Math.toRadians(mStartAngle - 180));
double sin = Math.sin(Math.toRadians(mStartAngle - 180));
float x0 = (float) (mPadding + mStrokeWidth + mLength1 / 3 + (mRadius - mLength1 / 3) * (1 - cos));
float y0 = (float) (mPadding + mStrokeWidth + mLength1 / 3 + (mRadius - mLength1 / 3) * (1 - sin));
float x2 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * cos);
float y2 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * sin);
float lx0 = (float) (mPadding + mStrokeWidth + mRadius * (1 - cos));
float ly0 = (float) (mPadding + mStrokeWidth + mRadius * (1 - sin));
float lx1 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * cos);
float ly1 = (float) (mPadding + mStrokeWidth + mRadius - (mRadius - mLength1) * sin);
if (mStepCount > 0) {
canvas.drawLine(lx0, ly0, lx1, ly1, mProgressPaint);
}
float angle = (float) (mSweepAngle * 1f / (mSection * mPortion));
for (int i = 0; i <= getProgressCell(); i++) {
if (i % mPortion == 0) {
mProgressPaint.setStrokeWidth(mStrokeWidth);
canvas.drawLine(lx0, ly0, lx1, ly1, mProgressPaint);
} else {
canvas.drawLine(x0, y0, x2, y2, mProgressPaint);
}
canvas.rotate(angle, mCenterX, mCenterY);
}
canvas.restore();
}
private void drawHeadText(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextAlign(Paint.Align.CENTER);
mPaint.setColor(ContextCompat.getColor(getContext(), R.color.dashboard_text_black1));
mPaint.setTextSize(sp2px(12));
mPaint.setTypeface(null);
canvas.drawText(mHeaderText, mCenterX, mCenterY - dp2px(55), mPaint);
}
private void drawStepCount(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setTextSize(sp2px(48));
mPaint.setColor(ContextCompat.getColor(getContext(), R.color.dashboard_text_black2));
Typeface dincond_black = Typeface.createFromAsset(ComponentContext.getContext().getAssets(), "fonts/DINCond-Black.otf");
mPaint.setTypeface(dincond_black);
mPaint.setTextSize(sp2px(48));
canvas.drawText(String.valueOf(mStepCount), mCenterX, mCenterY - dp2px(7), mPaint);
}
private void drawLongScaleText(Canvas canvas) {
float α;
float[] p;
float angle = mSweepAngle * 1f / mSection;
for (int i = 0; i <= mSection; i++) {
α = mStartAngle + angle * i;
p = getCoordinatePoint(mRadius - mLength2, α);
if (α % 360 > 135 && α % 360 < 225) {
mTextPaint.setTextAlign(Paint.Align.LEFT);
} else if ((α % 360 >= 0 && α % 360 < 45) || (α % 360 > 315 && α % 360 <= 360)) {
mTextPaint.setTextAlign(Paint.Align.RIGHT);
} else {
mTextPaint.setTextAlign(Paint.Align.CENTER);
}
mTextPaint.getTextBounds(mHeaderText, 0, mTexts[i].length(), mRectText);
int txtH = mRectText.height();
if (i <= 1 || i >= mSection - 1) {
canvas.drawText(mTexts[i], p[0], p[1] + txtH / 2, mTextPaint);
} else if (i == 3) {
canvas.drawText(mTexts[i], p[0] + txtH / 2, p[1] + txtH, mTextPaint);
} else if (i == mSection - 3) {
canvas.drawText(mTexts[i], p[0] - txtH / 2, p[1] + txtH, mTextPaint);
} else {
canvas.drawText(mTexts[i], p[0], p[1] + txtH + dp2px(3), mTextPaint);
}
}
}
private int getProgressCell() {
if (mStepCount <= mMin) {
return 0;
} else if (mStepCount > 0 && mStepCount <= mMax) {
double v = mMax / mSection / mPortion;
return (int) Math.floor(mStepCount / v);
} else {
return (int) (mSection * mPortion);
}
}
private int dp2px(int dp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
Resources.getSystem().getDisplayMetrics());
}
private int sp2px(int sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sp,
Resources.getSystem().getDisplayMetrics());
}
public float[] getCoordinatePoint(int radius, float angle) {
float[] point = new float[2];
double arcAngle = Math.toRadians(angle);
if (angle < 90) {
point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius);
point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);
} else if (angle == 90) {
point[0] = mCenterX;
point[1] = mCenterY + radius;
} else if (angle > 90 && angle < 180) {
arcAngle = Math.PI * (180 - angle) / 180.0;
point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius);
point[1] = (float) (mCenterY + Math.sin(arcAngle) * radius);
} else if (angle == 180) {
point[0] = mCenterX - radius;
point[1] = mCenterY;
} else if (angle > 180 && angle < 270) {
arcAngle = Math.PI * (angle - 180) / 180.0;
point[0] = (float) (mCenterX - Math.cos(arcAngle) * radius);
point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);
} else if (angle == 270) {
point[0] = mCenterX;
point[1] = mCenterY - radius;
} else {
arcAngle = Math.PI * (360 - angle) / 180.0;
point[0] = (float) (mCenterX + Math.cos(arcAngle) * radius);
point[1] = (float) (mCenterY - Math.sin(arcAngle) * radius);
}
return point;
}
public int getStepCount() {
return mStepCount;
}
public void setStepCount(int stepCount, boolean b) {
mStepCount = stepCount;
if (mStepCount < 0) {
StatisticsUtils.statisicsGrowing(StatisticConstants.EVENT_STEPCOUNTERROR, StatisticConstants.KEY_STEPCOUNT, String.valueOf(mStepCount));
}
mRefreshText = b;
postInvalidate();
}
public int getGoldCoin() {
return goldCoin;
}
public void refreshScale(int currentCount) {
mStepRecord = currentCount;
ValueAnimator valueAnimator = this.mValueAnimator;
if (valueAnimator == null) {
mValueAnimator = new ValueAnimator();
mValueAnimator.setDuration(2000);
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int intValue = ((Integer) animation.getAnimatedValue()).intValue();
setStepCount(intValue, false);
}
});
} else {
mValueAnimator.cancel();
}
mValueAnimator.setIntValues(new int[]{0, mMax, currentCount});
mValueAnimator.start();
}
}
<color name="dashboard_scale_gray">#6A6868</color>
<color name="dashboard_text_black1">#333333</color>
<color name="dashboard_text_black2">#000000</color>
|