Android自定义View弧线进度控件

所属分类: 软件编程 / Android 阅读数: 1102
收藏 0 赞 0 分享

这个是一个以弧线为依托的进度控件,主要包括了两个圆弧、一个圆、一个文本。

 

当我们点击开始按钮的时候,会出现一个动画,逐渐的出现进度,好了,下面开始我们的编码。

新建一个类,继承自View,实现三个构造方法,接着定义变量,初始化变量的数据。代码如下:

private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;

 private float length;

 private float mRadius;

 private float mCircleXY;

 private float mSweepValue = 0;

 private String mShowText = "0%";

 private RectF mRectF;

 public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView();
 }

 public MViewOne(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }

 public MViewOne(Context context) {
  super(context);
  initView();
 }

 private void initView() {
  mArcPaint = new Paint();
  mArcPaint.setStrokeWidth(50);
  mArcPaint.setAntiAlias(true);
  mArcPaint.setColor(Color.GREEN);
  mArcPaint.setStyle(Style.STROKE);

  mCirclePaint = new Paint();
  mCirclePaint.setColor(Color.GREEN);
  mCirclePaint.setAntiAlias(true);

  mTextPaint = new Paint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setColor(Color.RED);
  mTextPaint.setStrokeWidth(0);

  mPaint = new Paint();
  mPaint.setStrokeWidth(40);
  mPaint.setAntiAlias(true);
  mPaint.setColor(Color.YELLOW);
  mPaint.setStyle(Style.STROKE);


 }

可以看到,这里一共定义了四个画笔,两个画弧形,一个画文本,还有一个绘制圆。

在我们的onSizeChange方法里面,再给变量赋值。

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  length = w;
  mCircleXY = length / 2;
  mRadius = (float) (length * 0.5 / 2);

 }

这时候,圆的半径、圆的起绘点,都已经有值了。

下面开始绘制

@Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // 画圆
  mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),
    (float) (length * 0.9), (float) (length * 0.9));
  canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
  // 画弧线
  canvas.drawArc(mRectF, 270, 360, false, mPaint);

  canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);

  // 绘制文字
  float textWidth = mTextPaint.measureText(mShowText); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间

  canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);

 }

这个时候,全部的效果已经出来了,但是这个还是静态的,对外暴露一个方法,让数据可以动态的刷新

 public void setProgress(float mSweepValue) {
  float a = (float) mSweepValue;
  if (a != 0) {
   this.mSweepValue = (float) (360.0 * (a / 100.0));
   mShowText = mSweepValue + "%";
   Log.e("this.mSweepValue:", this.mSweepValue + "");
  } else {
   this.mSweepValue = 25;
   mShowText = 25 + "%";
  }

  invalidate();
 }

好了,所有的代码都在这里了,老规矩,最后我贴上全部的代码:

public class MViewOne extends View {
 private Paint mArcPaint, mCirclePaint, mTextPaint, mPaint;

 private float length;

 private float mRadius;

 private float mCircleXY;

 private float mSweepValue = 0;

 private String mShowText = "0%";

 private RectF mRectF;

 public MViewOne(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView();
 }

 public MViewOne(Context context, AttributeSet attrs) {
  super(context, attrs);
  initView();
 }

 public MViewOne(Context context) {
  super(context);
  initView();
 }

 private void initView() {
  mArcPaint = new Paint();
  mArcPaint.setStrokeWidth(50);
  mArcPaint.setAntiAlias(true);
  mArcPaint.setColor(Color.GREEN);
  mArcPaint.setStyle(Style.STROKE);

  mCirclePaint = new Paint();
  mCirclePaint.setColor(Color.GREEN);
  mCirclePaint.setAntiAlias(true);

  mTextPaint = new Paint();
  mTextPaint.setAntiAlias(true);
  mTextPaint.setColor(Color.RED);
  mTextPaint.setStrokeWidth(0);

  mPaint = new Paint();
  mPaint.setStrokeWidth(40);
  mPaint.setAntiAlias(true);
  mPaint.setColor(Color.YELLOW);
  mPaint.setStyle(Style.STROKE);


 }

 @Override
 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
  super.onSizeChanged(w, h, oldw, oldh);
  length = w;
  mCircleXY = length / 2;
  mRadius = (float) (length * 0.5 / 2);

 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // 画圆
  mRectF = new RectF((float) (length * 0.1), (float) (length * 0.1),
    (float) (length * 0.9), (float) (length * 0.9));
  canvas.drawCircle(mCircleXY, mCircleXY, mRadius, mCirclePaint);
  // 画弧线
  canvas.drawArc(mRectF, 270, 360, false, mPaint);

  canvas.drawArc(mRectF, 270, mSweepValue, false, mArcPaint);

  // 绘制文字
  float textWidth = mTextPaint.measureText(mShowText); //测量字体宽度,我们需要根据字体的宽度设置在圆环中间

  canvas.drawText(mShowText, (int)(length/2-textWidth/2), (int)(length/2+textWidth/2) , mTextPaint);

 }

 public void setProgress(float mSweepValue) {
  float a = (float) mSweepValue;
  if (a != 0) {
   this.mSweepValue = (float) (360.0 * (a / 100.0));
   mShowText = mSweepValue + "%";
   Log.e("this.mSweepValue:", this.mSweepValue + "");
  } else {
   this.mSweepValue = 25;
   mShowText = 25 + "%";
  }

  invalidate();
 }

}

谢谢阅读,学习重在坚持,贵在坚持。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

更多精彩内容其他人还在看

Android中加入名片扫描功能实例代码

这篇文章主要介绍了Android中加入名片扫描功能实例代码的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android仿微信发表说说实现拍照、多图上传功能

这篇文章主要为大家详细介绍了Android仿微信发表说说实现拍照、多图上传功能,使用Retrofit2.0技术,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

设置Android系统永不锁屏永不休眠的方法

在进行Android系统开发的时候,有些特定的情况需要设置系统永不锁屏,永不休眠。本篇文章给大家介绍Android 永不锁屏,开机不锁屏,删除设置中休眠时间选项,需要的朋友一起学习吧
收藏 0 赞 0 分享

Android Retrofit 2.0框架上传图片解决方案

这篇文章主要介绍了Android Retrofit 2.0框架上传一张与多张图片解决方案,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android自定义等待对话框

这篇文章主要为大家详细介绍了Android自定义等待对话框的实现方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Android中Window添加View的底层原理

这篇文章主要介绍了Android中Window添加View的底层原理,需要的朋友可以参考下
收藏 0 赞 0 分享

Android调用系统默认浏览器访问的方法

这篇文章主要介绍了Android调用系统默认浏览器访问的方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Android开发退出程序的方法汇总

Android程序有很多Activity,比如说主窗口A,调用了子窗口B,子窗口B又调用子窗口C,back返回子窗口B后,在B中如何关闭整个Android应用程序呢? 下面脚本之家小编就给大家介绍android开发退出程序的几种方法,感兴趣的朋友参考下吧
收藏 0 赞 0 分享

Android程序开发中单选按钮(RadioGroup)的使用详解

在android程序开发中,无论是单选按钮还是多选按钮都非常的常见,接下来通过本文给大家介绍Android程序开发中单选按钮(RadioGroup)的使用,需要的朋友参考下吧
收藏 0 赞 0 分享

Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中

这篇文章主要介绍了Android实现仿网易今日头条等自定义频道listview 或者grideview等item上移到另一个view中 的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多