Android自定义带动画圆环进度条
1.首先是自定义类
package com.yx.yxcustomprogress;import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;import java.util.ArrayList;public class ColorfulRingProgressView extends View {private float mPercent = 0f;//进度值默认为0 最大值为100private float mStrokeWidth = 0f;//圆环宽度private int mBgColor = 0xffe1e1e1;//默认背景颜色private float mStartAngle = 0f;//起点位置private int mFgColorStart = 0xffffe400;//渐变开始颜色private int mFgColorEnd = 0xffff4800;//渐变结束颜色private LinearGradient mShader = null;//线性渐变private Context mContext = null;private RectF mOval = null;private Paint mPaint = null;public ArrayList mList = null;//施工节点坐标集合private Float r = null;//半径private int distance = 100;//进度圈离边界的距离private int stage = 50;//施工阶段离进度圈的距离private int divide = 6;//将圆等分成几份private float share = 0f;//将一个圆等分成n时每份所占的度数private String mTitleText = null;private int mTitleTextColor = 0;private int mTitleTextSize = 0;private Rect mTextBound = null;private Paint mTextPaint = null;private float startPercent = 0;//上一次的进度private int flag = 0;//标记是第一次设置percent的值private Drawable[] drawablesCompleted = {getResources().getDrawable(R.mipmap.yqcompleted),getResources().getDrawable(R.mipmap.azcompleted),getResources().getDrawable(R.mipmap.jdcjcompleted),getResources().getDrawable(R.mipmap.sdcompleted),getResources().getDrawable(R.mipmap.ntcompleted),getResources().getDrawable(R.mipmap.mgwgcompleted)};private Drawable[] drawablesNostart = {getResources().getDrawable(R.mipmap.yqnostart),getResources().getDrawable(R.mipmap.aznostart),getResources().getDrawable(R.mipmap.jdcjnostart),getResources().getDrawable(R.mipmap.sdnostart),getResources().getDrawable(R.mipmap.ntnostart),getResources().getDrawable(R.mipmap.mgwgnostart)};public ColorfulRingProgressView(Context context, AttributeSet attrs) {super(context, attrs);this.mContext = context;TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ColorfulRingProgressView, 0, 0);try {mBgColor = a.getColor(R.styleable.ColorfulRingProgressView_bgColor, 0xffe1e1e1);mFgColorEnd = a.getColor(R.styleable.ColorfulRingProgressView_fgColorEnd, 0xffff4800);mFgColorStart = a.getColor(R.styleable.ColorfulRingProgressView_fgColorStart, 0xffffe400);mPercent = a.getFloat(R.styleable.ColorfulRingProgressView_percent, 0);mStartAngle = a.getFloat(R.styleable.ColorfulRingProgressView_startAngle, 0) + 270;mStrokeWidth = a.getDimensionPixelSize(R.styleable.ColorfulRingProgressView_strokeWidth, dp2px(21));mTitleText = a.getString(R.styleable.ColorfulRingProgressView_mTitleText);mTitleTextColor = a.getColor(R.styleable.ColorfulRingProgressView_mTitleTextColor, Color.RED);mTitleTextSize = a.getDimensionPixelSize(R.styleable.ColorfulRingProgressView_mTitleTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics()));} finally {a.recycle();}init();}private void init() {startPercent = mPercent;mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);mPaint.setStrokeWidth(mStrokeWidth);mPaint.setStrokeCap(Paint.Cap.ROUND);share = (float) (100) / divide;mTextBound = new Rect();mTextPaint = new Paint();mTextPaint.setTextSize(mTitleTextSize);mTextPaint.setColor(mTitleTextColor);// 计算描绘字体所需要的范围mTextPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mTextBound);}private int dp2px(float dp) {return (int) (mContext.getResources().getDisplayMetrics().density * dp + 0.5f);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int centerX = getWidth() / 2;// 获得圆心的x坐标int centerY = getHeight() / 2;// 获得圆心的y坐标/** step1、画背景圈 */mPaint.setShader(null);mPaint.setColor(mBgColor);// 设定阴影 (柔边, X轴位移, Y轴位移, 阴影颜色)mPaint.setShadowLayer(2, 3, 3, 0x8e1b1a);canvas.drawArc(mOval, 0, 360, false, mPaint);/** step2、画进度圈 */mPaint.setShader(mShader);canvas.drawArc(mOval, mStartAngle, mPercent * 3.6f, false, mPaint);/** step3、画百分比 */mPaint.setAntiAlias(true);// 消除锯齿//计算文字的起始点//计算baseline(参考文献) http://blog.csdn.net/sirnuo/article/details/21165665Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();float descentY = centerY + fontMetrics.descent;// 设置字符串的左边在屏幕的中间mTextPaint.setTextAlign(Paint.Align.CENTER);//根据要显示的百分比与圆圈进度的百分比之比来换算要显示的百分比canvas.drawText((int) (getPercent() * (Float.parseFloat(getmTitleText()) / startPercent)) + "", centerX, descentY, mTextPaint);//100/** step3、画施工节点 *///这个地方写的比较烂,暂时不知道有什么更好的思路。for (int i = 0; i < mList.size(); i++) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesNostart[i]).getBitmap(), (float) mList.get(i).x - drawablesNostart[i].getIntrinsicWidth() * 0.5f, (float) mList.get(i).y - drawablesNostart[i].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();}if (getPercent() >= share * 0 && getPercent() < share * 1) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();} else if (getPercent() >= share * 1 && getPercent() < share * 2) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[3]).getBitmap(), (float) mList.get(3).x - drawablesCompleted[3].getIntrinsicWidth() * 0.5f, (float) mList.get(3).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();} else if (getPercent() >= share * 2 && getPercent() < share * 3) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[3]).getBitmap(), (float) mList.get(3).x - drawablesCompleted[3].getIntrinsicWidth() * 0.5f, (float) mList.get(3).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[4]).getBitmap(), (float) mList.get(4).x - drawablesCompleted[4].getIntrinsicWidth() * 0.5f, (float) mList.get(4).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();} else if (getPercent() >= share * 3 && getPercent() < share * 4) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[3]).getBitmap(), (float) mList.get(3).x - drawablesCompleted[3].getIntrinsicWidth() * 0.5f, (float) mList.get(3).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[4]).getBitmap(), (float) mList.get(4).x - drawablesCompleted[4].getIntrinsicWidth() * 0.5f, (float) mList.get(4).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[5]).getBitmap(), (float) mList.get(5).x - drawablesCompleted[5].getIntrinsicWidth() * 0.5f, (float) mList.get(5).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();} else if (getPercent() >= share * 4 && getPercent() < share * 5) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[3]).getBitmap(), (float) mList.get(3).x - drawablesCompleted[3].getIntrinsicWidth() * 0.5f, (float) mList.get(3).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[4]).getBitmap(), (float) mList.get(4).x - drawablesCompleted[4].getIntrinsicWidth() * 0.5f, (float) mList.get(4).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[5]).getBitmap(), (float) mList.get(5).x - drawablesCompleted[5].getIntrinsicWidth() * 0.5f, (float) mList.get(5).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[0]).getBitmap(), (float) mList.get(0).x - drawablesCompleted[0].getIntrinsicWidth() * 0.5f, (float) mList.get(0).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();} else if (getPercent() >= share * 5 && getPercent() <= share * 6) {canvas.save();canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[2]).getBitmap(), (float) mList.get(2).x - drawablesCompleted[2].getIntrinsicWidth() * 0.5f, (float) mList.get(2).y - drawablesCompleted[0].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[3]).getBitmap(), (float) mList.get(3).x - drawablesCompleted[3].getIntrinsicWidth() * 0.5f, (float) mList.get(3).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[4]).getBitmap(), (float) mList.get(4).x - drawablesCompleted[4].getIntrinsicWidth() * 0.5f, (float) mList.get(4).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[5]).getBitmap(), (float) mList.get(5).x - drawablesCompleted[5].getIntrinsicWidth() * 0.5f, (float) mList.get(5).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[0]).getBitmap(), (float) mList.get(0).x - drawablesCompleted[0].getIntrinsicWidth() * 0.5f, (float) mList.get(0).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.drawBitmap(((BitmapDrawable) drawablesCompleted[1]).getBitmap(), (float) mList.get(1).x - drawablesCompleted[1].getIntrinsicWidth() * 0.5f, (float) mList.get(1).y - drawablesCompleted[1].getIntrinsicHeight() * 0.5f, mPaint);canvas.restore();}}//求一个圆划分成n等份,r是半径,(x,y)为圆心坐标的所有坐标值private ArrayList onCoordinatePoints(int n, double r, double x, double y) {ArrayList mXYZs = new ArrayList();// n为分成了多少份for (int i = 1; i <= n; i++) {double rad = (2 * Math.PI / n) * (double) i;rad += Math.PI / 2f;double mx = r * Math.cos(rad);double my = r * Math.sin(rad);//加上圆心坐标mXYZs.add(new XYZ(mx + x, my + y));}return mXYZs;}class XYZ {public double x;public double y;public XYZ(double x, double y) {this.x = x;this.y = y;}}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);updateOval();mShader = new LinearGradient(mOval.left, mOval.top,mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);}public float getPercent() {return mPercent;}public void setPercent(float mPercent) {this.mPercent = mPercent;if (flag == 0) {flag++;startPercent = mPercent;}refreshTheLayout();}public String getmTitleText() {return mTitleText;}public void setmTitleText(String mTitleText) {this.mTitleText = mTitleText;refreshTheLayout();}public float getStrokeWidth() {return mStrokeWidth;}public void setStrokeWidth(float mStrokeWidth) {this.mStrokeWidth = mStrokeWidth;mPaint.setStrokeWidth(mStrokeWidth);updateOval();refreshTheLayout();}private void updateOval() {//修改:增加50距离,来画外圈节点int xp = getPaddingLeft() + distance + getPaddingRight() + distance;int yp = getPaddingBottom() + distance + getPaddingTop() + distance;mOval = new RectF(getPaddingLeft() + distance + mStrokeWidth, getPaddingTop() + distance + mStrokeWidth,getPaddingLeft() + distance + (getWidth() - xp) - mStrokeWidth,getPaddingTop() + distance + (getHeight() - yp) - mStrokeWidth);//计算rr = (mOval.right - mOval.left) / 2;//增加半径长度,画节点mList = onCoordinatePoints(divide, r + stage, r + mOval.left, r + mOval.top);}public void setStrokeWidthDp(float dp) {this.mStrokeWidth = dp2px(dp);mPaint.setStrokeWidth(mStrokeWidth);updateOval();refreshTheLayout();}public void refreshTheLayout() {invalidate();requestLayout();}public int getFgColorStart() {return mFgColorStart;}public void setFgColorStart(int mFgColorStart) {this.mFgColorStart = mFgColorStart;mShader = new LinearGradient(mOval.left, mOval.top,mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);refreshTheLayout();}public int getFgColorEnd() {return mFgColorEnd;}public void setFgColorEnd(int mFgColorEnd) {this.mFgColorEnd = mFgColorEnd;mShader = new LinearGradient(mOval.left, mOval.top,mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);refreshTheLayout();}public float getStartAngle() {return mStartAngle;}public void setStartAngle(float mStartAngle) {this.mStartAngle = mStartAngle + 270;refreshTheLayout();}
}
2.MainActivity
package com.yx.yxcustomprogress;import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.animation.LinearInterpolator;public class MainActivity extends Activity {private ColorfulRingProgressView project_schedul_crpv = null;private ObjectAnimator anim = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.activity_main);project_schedul_crpv = (ColorfulRingProgressView) findViewById(R.id.project_schedul_crpv);project_schedul_crpv.setPercent(70);//设置进度条的进度,最大值为100project_schedul_crpv.setmTitleText("60");//设置百分比,最大值为100anim = ObjectAnimator.ofFloat(project_schedul_crpv, "percent", 0, (project_schedul_crpv).getPercent());//设置动画anim.setInterpolator(new LinearInterpolator());anim.setDuration(2000);anim.start();project_schedul_crpv.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {anim.start();}});}
}
3.效果图
点我下载Demo
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
