标签:
package com.totcy.magicprogress; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator; /** * Description 酷炫水平进度条 * Author: tu * Date: 2016-08-22 * Time: 14:59 */ public class HorizonalProgress extends View { private int viewWidth;//view的宽度 private int viewHigth;//view的高度 private Paint mPaint;//画笔 212 62 96 private int colorSecondProgress = Color.argb(255,229,237,245);//背景圆颜色,进度条背景色 private int colorProgress = Color.argb(255,19,146,255);//背景圆颜色,一级进度条颜色 private int progressHeight = 30;//进度条的高度 private RectF rectF = new RectF(); private int curProgress = 0; //必须小于等于100 大于0 private int oldProgress = 0; public void setColorSecondProgress(int colorSecondProgress) { this.colorSecondProgress = colorSecondProgress; } public void setColorProgress(int colorProgress) { this.colorProgress = colorProgress; } public void setProgressHeight(int progressHeight) { this.progressHeight = progressHeight; } public void setCurProgress(int curProgress) { this.curProgress = curProgress; invalidate(); } public HorizonalProgress(Context context) { this(context,null); } public HorizonalProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public HorizonalProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ //初始化坐标画笔 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaint.setColor(colorSecondProgress); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.STROKE);//空心 curProgress = 0; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int height; int width; //宽度测量 if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = getMeasuredWidth(); } viewWidth = width; //高度测量 if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = getMeasuredHeight(); } //进度条的高度根据 viewHigth = progressHeight; setMeasuredDimension(width, viewHigth); } /** * 绘制进度 * @param canvas */ private void drawProgress(Canvas canvas){ rectF.left = 0; rectF.right = viewWidth; rectF.top = 0; rectF.bottom = viewHigth; mPaint.setStyle(Paint.Style.FILL); mPaint.setColor(colorSecondProgress); //灰色背景 canvas.drawRoundRect(rectF,viewHigth/2,viewHigth/2,mPaint); //进度 mPaint.setColor(colorProgress); rectF.right = curProgress * viewWidth / 100; canvas.drawRoundRect(rectF,viewHigth/2,viewHigth/2,mPaint); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawProgress(canvas); } public void setProgress(int progress){ if (progress < 0 || progress > 100) return; ObjectAnimator o = ObjectAnimator.ofInt(this, "curProgress", oldProgress, progress); o.setDuration(1000); o.setInterpolator(new DecelerateInterpolator()); o.start(); oldProgress = progress; } }
package com.totcy.magicprogress; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.util.AttributeSet; import android.view.View; import android.view.animation.DecelerateInterpolator; /** * Description 圆形装逼进度条 * Author: tu * Date: 2016-08-19 * Time: 14:33 */ public class CircleProgress extends View{ private float textSize = getResources().getDimension(R.dimen.text_size_14); private float dotX, dotY;//圆点xy private int viewWidth;//view的宽度 private int viewHigth;//view的高度 private Paint mPaint,mPaintArc;//画笔 212 62 96 private int colorBg = Color.argb(255,54,68,76);//背景圆颜色 private int colorWhite = Color.argb(255,255,255,255);//文字颜色 private int colorBlack = Color.argb(255,34,49,59);//第二刻度颜色 private int colorBlue = Color.argb(255,94,248,249);//刻度颜色 private int pandding = 10; private RectF rectF; private float radius = 10;//半径 private float scaleLineLenth = 3;//刻度线长 private int scaleAngle = 10;//刻度间隔 private int scaleWidth = 5;//刻度宽度 private int curProgress = 0;//0 ~ 100进度 当前进度 private int oldProgress = 0; public void setColorBlue(int colorBlue) { this.colorBlue = colorBlue; } public void setTextSize(float textSize) { this.textSize = textSize; } public int getCurProgress() { return curProgress; } public void setCurProgress(int curProgress) { this.curProgress = curProgress; invalidate(); } public CircleProgress(Context context) { this(context,null); } public CircleProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public CircleProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } /** * 初始化画笔 */ private void init(Context context) { //初始化坐标画笔 mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaintArc = new Paint(Paint.ANTI_ALIAS_FLAG);// mPaint.setColor(colorWhite); mPaintArc.setColor(colorBg); mPaint.setAntiAlias(true); mPaintArc.setAntiAlias(true); mPaint.setTextSize(15); mPaint.setStyle(Paint.Style.STROKE);//空心 //当前进度 } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int widthMode = MeasureSpec.getMode(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int height; int width; //宽度测量 if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = getMeasuredWidth(); } dotX = width / 2; viewWidth = width; //高度测量 if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = getMeasuredHeight(); } viewHigth = height; dotY = height / 2; radius = dotX-(getPaddingLeft() + getPaddingRight())/2; scaleLineLenth = radius/3; rectF = new RectF(dotX - radius, dotY - radius, dotX + radius, dotY + radius); setMeasuredDimension(width, height); } private void drawProgress(Canvas canvas){ if(mPaintArc == null){ return; } //圆 mPaintArc.setStyle(Paint.Style.FILL); canvas.drawCircle(dotX, dotY, radius, mPaintArc); //中心进度值 mPaint.setStyle(Paint.Style.FILL_AND_STROKE);//实心 mPaint.setTextAlign(Paint.Align.CENTER); mPaint.setStrokeWidth(1); mPaint.setTextSize(textSize); mPaint.setColor(colorWhite); canvas.drawText(curProgress + "%",dotX, dotY+getResources().getDimension(R.dimen.text_size_14)/2 ,mPaint); //黑色刻度 12点钟方向为起始点(-90°),正时针方法绘制 for (int angle = -90; angle <= 270; angle += scaleAngle){ float xY[] = caculCoordinate(angle); if(xY != null) { mPaint.setStrokeWidth(scaleWidth); mPaint.setColor(colorBlack); canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint); } } //进度算法 //360 除与 scaleAngle(进度间隔10) = 36; 再拿进度总数100换算当前进度 //算出当前进度占几个刻度 int curProgressCount = curProgress * (360/scaleAngle) /100; int angleStart = -90; for (int count = 0; count < curProgressCount;count ++){ float xY[] = caculCoordinate(angleStart); if(xY != null) { mPaint.setStrokeWidth(scaleWidth); mPaint.setColor(colorBlue); canvas.drawLine(xY[0], xY[1],xY[2],xY[3], mPaint); } angleStart += scaleAngle; } } /** * 根据圆心角 计算圆周上的坐标 * @param angle * @return xY[0] startX; xY[1] startY; xY[2] endX; xY[3] endY; */ private float[] caculCoordinate(int angle){ //angle >180 angle = angle -180 float xY[] = new float[4]; //角度处理 int tempAngle = Math.abs(angle); float tempScaleLineLenth = scaleLineLenth; if(270 > tempAngle && tempAngle >= 180) { tempAngle = tempAngle - 180; xY[0] = dotX - getCoordinateX(tempAngle,radius); xY[1] = dotY - getCoordinateY(tempAngle,radius); xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth); }else if(180 > tempAngle && tempAngle > 90){ tempAngle = 180 - tempAngle; xY[0] = dotX - getCoordinateX(tempAngle,radius); xY[1] = dotY + getCoordinateY(tempAngle,radius); xY[2] = xY[0] + getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth); }else if(90 >= tempAngle && tempAngle >= 0){ xY[0] = dotX + getCoordinateX(tempAngle,radius); xY[1] = angle < 0 ? dotY - getCoordinateY(tempAngle,radius) : dotY + getCoordinateY(tempAngle,radius); xY[2] = xY[0] - getCoordinateX(tempAngle,tempScaleLineLenth); xY[3] = angle < 0 ? xY[1] + getCoordinateY(tempAngle,tempScaleLineLenth) : xY[1] - getCoordinateY(tempAngle,tempScaleLineLenth); } return xY; } /** * 获取圆周上y值相对值 * @param tempAngle * @param radius 算开始坐标是传半径,算结束坐标时传刻度线的长度 * @return */ private float getCoordinateY(int tempAngle,float radius){ //利用正弦函数算出y坐标 return (float) (Math.sin(tempAngle*Math.PI/180)*(radius - 15)); //10 是离圆弧的距离 } /** * 获取圆周上X值相对值 * @param tempAngle * @return */ private float getCoordinateX(int tempAngle,float radius){ //利用余弦函数算出y坐标 return (float) (Math.cos(tempAngle*Math.PI/180)*(radius - 15)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawProgress(canvas); } public void setProgress(int progress){ if (progress < 0 || progress > 100) return; ObjectAnimator o = ObjectAnimator.ofInt(this, "curProgress", oldProgress, progress); o.setDuration(1000); o.setInterpolator(new DecelerateInterpolator()); o.start(); oldProgress = progress; } }
package com.totcy.magicprogress; import android.R.dimen; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Color; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.widget.FrameLayout; import android.widget.RelativeLayout; /** * Description 组合装逼进度 * Author: tu * Date: 2016-08-22 * Time: 15:36 */ public class MyProgress extends RelativeLayout { private Context context; private float textProgressSize;//圆形进度条中间文字 private float horizonalProgressHeight;//横条高度 private float circleProgressRadus;//圆形半径 private int colorProgress;//进度条颜色,圆盘刻度颜色 private int colorSecondProgress;//进度条背景颜色 private boolean flagPaint = true;//绘图标志 int newProgress; private CircleProgress mCircleProgress; private HorizonalProgress mHorizonalProgress; //private int touchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();//最小滑动阀值 public MyProgress(Context context) { this(context,null); } public MyProgress(Context context, AttributeSet attrs) { this(context, attrs,0); } public MyProgress(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; init(attrs); ViewTreeObserver vto = getViewTreeObserver(); vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { if(flagPaint){ flagPaint = false; initHorizonalProgress(); }else{ } } }); } private void init(AttributeSet attrs){ flagPaint = true; //获取自定义xml属性 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.myMagicProgress); int n = typedArray.getIndexCount(); for (int i = 0; i < n; i++) { int attr = typedArray.getIndex(i); switch (attr) { case R.styleable.myMagicProgress_circleProgressRadus: // Log.e("tag", "typedArray.getDimension(attr, 0)="+typedArray.getDimension(attr, 0)+",typedArray.getDimension(i, 0)="+typedArray.getDimension(i, 0)); circleProgressRadus = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_horizonalProgressHeight: horizonalProgressHeight = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_textProgressSize: textProgressSize = typedArray.getDimension(attr, 0); break; case R.styleable.myMagicProgress_colorProgress: colorProgress = typedArray.getColor(attr, Color.GRAY); break; case R.styleable.myMagicProgress_colorSecondProgress: colorSecondProgress = typedArray.getColor(attr, Color.GRAY); break; default: break; } } //横向进度条稍后设置参数,需要圆形进度条绘图完成,根据宽度绘制左右边距 mHorizonalProgress = new HorizonalProgress(getContext()); mHorizonalProgress.setProgressHeight((int) horizonalProgressHeight); mHorizonalProgress.setColorSecondProgress(colorSecondProgress); mHorizonalProgress.setColorProgress(colorProgress); int radus = (int) circleProgressRadus; mCircleProgress = new CircleProgress(getContext()); mCircleProgress.setTextSize(textProgressSize); mCircleProgress.setColorBlue(colorProgress); LayoutParams cp_lp = new RelativeLayout.LayoutParams(radus,radus); cp_lp.addRule(RelativeLayout.CENTER_VERTICAL); mCircleProgress.setLayoutParams(cp_lp); addView(mHorizonalProgress); addView(mCircleProgress); initView(); } private float mDownX; private void initView(){ mCircleProgress.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mDownX = event.getX(); // Log.d("Tag",event.getX() + ":" + event.getRawX()); break; case MotionEvent.ACTION_MOVE: // Log.d("Tag",event.getX() + ":" + event.getRawX()); float disX = event.getX() - mDownX; float llX = mCircleProgress.getX() + disX; // Log.e("tag", "disX="+disX+",llX="+llX+",mHorizonalProgress.getWidth()="+mHorizonalProgress.getWidth()); //校正边界,反正滑块划出 llX = checkoundary(llX); mCircleProgress.setX(llX); //计算进度条百分比 newProgress = getProgress(llX); //更新进度条 updateProgress(newProgress); break; case MotionEvent.ACTION_UP: break; default: break; } return true; } }); } /** * 绘制横向进度条 */ public void initHorizonalProgress(){ // Log.e("tag", "mCircleProgress.getWidth()="+mCircleProgress.getWidth()); //设置边距,左右空出滑块半径的距离 LayoutParams hp_lp = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,(int) horizonalProgressHeight); hp_lp.leftMargin = mCircleProgress.getWidth()/2; hp_lp.rightMargin = mCircleProgress.getWidth()/2; hp_lp.addRule(RelativeLayout.CENTER_VERTICAL); mHorizonalProgress.setLayoutParams(hp_lp); } /** * 校正边界 * @return */ public float checkoundary(float llX){ if(llX<0){ llX = 0f; }else if(llX>mHorizonalProgress.getWidth()){ llX = mHorizonalProgress.getWidth(); } return llX; } /** * 换算百分比 */ public int getProgress(float llX){ return (int) ((llX/mHorizonalProgress.getWidth())*100); } /** * 更新进度 * @param newProgress */ public void updateProgress(int newProgress){ // Log.e("tag", "newProgress="+newProgress); mCircleProgress.setProgress(newProgress); mHorizonalProgress.setProgress(newProgress); } }
标签:
原文地址:http://blog.csdn.net/tl792814781/article/details/52289864