文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android怎么自定义View实现圆弧进度效果

2023-07-06 03:48

关注

这篇文章主要介绍“Android怎么自定义View实现圆弧进度效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android怎么自定义View实现圆弧进度效果”文章能帮助大家解决问题。

技术实现

ArcView继承自View

Canvas(画布)

Paint(画笔)

效果图:类似于QQ的计步效果

Android怎么自定义View实现圆弧进度效果

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实现圆弧进度效果”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯