这篇文章主要介绍“Android怎么自定义View实现圆弧进度效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么自定义View实现圆弧进度效果”文章能帮助大家解决问题。
技术实现
ArcView继承自View
Canvas(画布)
Paint(画笔)
效果图:类似于QQ的计步效果
1.继承自View
重写3个构造方法(新的API中的构造方法是4个)
public ArcView(Context context) { this(context,null); }public ArcView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0); } public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); //init(); }
重写View的OnDraw方法
@SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); centerX=getWidth()/2; centerY=getHeight()/2; //初始化paint initPaint(); //绘制弧度 drawArc(canvas); //绘制文本 drawText(canvas); }注:这里的paint初始化我放在了onDraw方法中进行的,当然你也可以放在有三个参数的构造方法中初始化。
2.Paint初始化
圆弧的画笔mArcPaint
//圆弧的paint mArcPaint=new Paint(Paint.ANTI_ALIAS_FLAG); //抗锯齿 mArcPaint.setAntiAlias(true); mArcPaint.setColor(Color.parseColor("#666666")); //设置透明度(数值为0-255) mArcPaint.setAlpha(100); //设置画笔的画出的形状 mArcPaint.setStrokeJoin(Paint.Join.ROUND); mArcPaint.setStrokeCap(Paint.Cap.ROUND); //设置画笔类型 mArcPaint.setStyle(Paint.Style.STROKE); mArcPaint.setStrokeWidth(dp2px(mStrokeWith));
文字的画笔mTextPaint
//中心文字的paintmTextPaint=new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setColor(Color.parseColor("#FF4A40"));//设置文本的对齐方式mTextPaint.setTextAlign(Paint.Align.CENTER);//mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.dp_12));mTextPaint.setTextSize(dp2px(25));
3.Canvas绘制
圆弧的绘制
private void drawArc(Canvas canvas) { //绘制圆弧背景 RectF mRectF=new RectF(mStrokeWith+dp2px(5),mStrokeWith+dp2px(5),getWidth()-mStrokeWith-dp2px(5),getHeight()-mStrokeWith); canvas.drawArc(mRectF,startAngle,mAngle,false,mArcPaint); //绘制当前数值对应的圆弧 mArcPaint.setColor(Color.parseColor("#FF4A40")); //根据当前数据绘制对应的圆弧 canvas.drawArc(mRectF,startAngle,mIncludedAngle,false,mArcPaint); }
文本的绘制
private void drawText(Canvas canvas) { Rect mRect=new Rect(); String mValue=String.valueOf(mAnimatorValue); //绘制中心的数值 mTextPaint.getTextBounds(mValue,0,mValue.length(),mRect); canvas.drawText(String.valueOf(mAnimatorValue),centerX,centerY+mRect.height(),mTextPaint); //绘制中心文字描述 mTextPaint.setColor(Color.parseColor("#999999")); mTextPaint.setTextSize(dp2px(12)); mTextPaint.getTextBounds(mDes,0,mDes.length(),mRect); canvas.drawText(mDes,centerX,centerY+2*mRect.height()+dp2px(10),mTextPaint); //绘制最小值 String minValue=String.valueOf(mMinValue); String maxValue=String.valueOf(mMaxValue); mTextPaint.setTextSize(dp2px(18)); mTextPaint.getTextBounds(minValue,0,minValue.length(),mRect); canvas.drawText(minValue, (float) (centerX-0.6*centerX-dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint); //绘制最大值 mTextPaint.getTextBounds(maxValue,0,maxValue.length(),mRect); canvas.drawText(maxValue, (float) (centerX+0.6*centerX+dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint); }
4.添加动画效果及数据
动画效果
private void setAnimation(float startAngle, float currentAngle,int currentValue, int time) { //绘制当前数据对应的圆弧的动画效果 ValueAnimator progressAnimator = ValueAnimator.ofFloat(startAngle, currentAngle); progressAnimator.setDuration(time); progressAnimator.setTarget(mIncludedAngle); progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { mIncludedAngle = (float) animation.getAnimatedValue(); //重新绘制,不然不会出现效果 postInvalidate(); } }); //开始执行动画 progressAnimator.start(); //中心数据的动画效果 ValueAnimator valueAnimator = ValueAnimator.ofInt(mAnimatorValue, currentValue); valueAnimator.setDuration(2500); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mAnimatorValue = (int) valueAnimator.getAnimatedValue(); postInvalidate(); } }); valueAnimator.start(); }
数据添加
public void setValues(int minValue,int maxValue, int currentValue,String des) { mDes=des; mMaxValue=maxValue; mMinValue=minValue; //完全覆盖背景弧度 if (currentValue maxValue) { currentValue = maxValue; } //计算弧度比重 float scale = (float) currentValue / maxValue; //计算弧度 float currentAngle = scale * mAngle; //开始执行动画 setAnimation(0, currentAngle, currentValue,2500);
完整代码:
public class ArcView extends View {//根据数据显示的圆弧Paintprivate Paint mArcPaint;//文字描述的paintprivate Paint mTextPaint;//圆弧开始的角度private float startAngle=135;//圆弧结束的角度private float endAngle=45;//圆弧背景的开始和结束间的夹角大小private float mAngle=270;//当前进度夹角大小private float mIncludedAngle=0;//圆弧的画笔的宽度private float mStrokeWith=10;//中心的文字描述private String mDes="";//动画效果的数据及最大/小值private int mAnimatorValue,mMinValue,mMaxValue;//中心点的XY坐标private float centerX,centerY;public ArcView(Context context) {this(context,null);}public ArcView(Context context, @Nullable AttributeSet attrs) {this(context, attrs,0);}public ArcView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);//init();}private void initPaint() {//圆弧的paintmArcPaint=new Paint(Paint.ANTI_ALIAS_FLAG);//抗锯齿mArcPaint.setAntiAlias(true);mArcPaint.setColor(Color.parseColor("#666666"));//设置透明度(数值为0-255)mArcPaint.setAlpha(100);//设置画笔的画出的形状mArcPaint.setStrokeJoin(Paint.Join.ROUND);mArcPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔类型mArcPaint.setStyle(Paint.Style.STROKE);mArcPaint.setStrokeWidth(dp2px(mStrokeWith));//中心文字的paintmTextPaint=new Paint();mTextPaint.setAntiAlias(true);mTextPaint.setColor(Color.parseColor("#FF4A40"));//设置文本的对齐方式mTextPaint.setTextAlign(Paint.Align.CENTER);//mTextPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.dp_12));mTextPaint.setTextSize(dp2px(25));}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);centerX=getWidth()/2;centerY=getHeight()/2;//初始化paintinitPaint();//绘制弧度drawArc(canvas);//绘制文本drawText(canvas);}private void drawText(Canvas canvas) {Rect mRect=new Rect();String mValue=String.valueOf(mAnimatorValue);//绘制中心的数值mTextPaint.getTextBounds(mValue,0,mValue.length(),mRect);canvas.drawText(String.valueOf(mAnimatorValue),centerX,centerY+mRect.height(),mTextPaint);//绘制中心文字描述mTextPaint.setColor(Color.parseColor("#999999"));mTextPaint.setTextSize(dp2px(12));mTextPaint.getTextBounds(mDes,0,mDes.length(),mRect);canvas.drawText(mDes,centerX,centerY+2*mRect.height()+dp2px(10),mTextPaint);//绘制最小值String minValue=String.valueOf(mMinValue);String maxValue=String.valueOf(mMaxValue);mTextPaint.setTextSize(dp2px(18));mTextPaint.getTextBounds(minValue,0,minValue.length(),mRect);canvas.drawText(minValue, (float) (centerX-0.6*centerX-dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);//绘制最大指mTextPaint.getTextBounds(maxValue,0,maxValue.length(),mRect);canvas.drawText(maxValue, (float) (centerX+0.6*centerX+dp2px(5)), (float) (centerY+0.75*centerY+mRect.height()+dp2px(5)),mTextPaint);}private void drawArc(Canvas canvas) {//绘制圆弧背景RectF mRectF=new RectF(mStrokeWith+dp2px(5),mStrokeWith+dp2px(5),getWidth()-mStrokeWith-dp2px(5),getHeight()-mStrokeWith);canvas.drawArc(mRectF,startAngle,mAngle,false,mArcPaint);//绘制当前数值对应的圆弧mArcPaint.setColor(Color.parseColor("#FF4A40"));//根据当前数据绘制对应的圆弧canvas.drawArc(mRectF,startAngle,mIncludedAngle,false,mArcPaint);}private void setAnimation(float startAngle, float currentAngle,int currentValue, int time) {//绘制当前数据对应的圆弧的动画效果ValueAnimator progressAnimator = ValueAnimator.ofFloat(startAngle, currentAngle);progressAnimator.setDuration(time);progressAnimator.setTarget(mIncludedAngle);progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mIncludedAngle = (float) animation.getAnimatedValue();//重新绘制,不然不会出现效果postInvalidate();}});//开始执行动画progressAnimator.start();//中心数据的动画效果ValueAnimator valueAnimator = ValueAnimator.ofInt(mAnimatorValue, currentValue);valueAnimator.setDuration(2500);valueAnimator.setInterpolator(new LinearInterpolator());valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator valueAnimator) {mAnimatorValue = (int) valueAnimator.getAnimatedValue();postInvalidate();}});valueAnimator.start();}public void setValues(int minValue,int maxValue, int currentValue,String des) {mDes=des;mMaxValue=maxValue;mMinValue=minValue;//完全覆盖if (currentValue maxValue) {currentValue = maxValue;}//计算弧度比重float scale = (float) currentValue / maxValue;//计算弧度float currentAngle = scale * mAngle;//开始执行动画setAnimation(0, currentAngle, currentValue,2500);}public float dp2px(float dp) {DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();return dp * metrics.density;}}
关于“Android怎么自定义View实现圆弧进度效果”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。