Android实现环形进度条

 更新时间:2018年07月06日 08:39:41   作者:qq_14876133  
这篇文章主要为大家详细介绍了Android实现环形进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一个通俗易懂的环形进度条,可以定制颜色角度,监听进度。

定义一个attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <declare-styleable name="CircleProgressView">
  <!--画笔宽度-->
  <attr name="progress_width" format="dimension" />
  <!--画笔颜色-->
  <attr name="progress_color" format="color" />
  <!--加载进度起始位置-->
  <attr name="location_start" format="enum">
   <enum name="left" value="1" />
   <enum name="top" value="2" />
   <enum name="right" value="3" />
   <enum name="bottom" value="4" />
  </attr>
 </declare-styleable>
</resources>

自定义CircleProgressView

package com.sample.circleprogressview.widget;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.sample.circleprogressview.R;


/**
 * 普通环形进度条
 */
public class CircleProgressView extends View {
 private int mCurrent;//当前进度
 private Paint mBgPaint;//背景弧线paint
 private Paint mProgressPaint;//进度Paint
 private float mProgressWidth;//进度条宽度
 private int mProgressColor = Color.RED;//进度条颜色
 private int locationStart;//起始位置
 private float startAngle;//开始角度
 private ValueAnimator mAnimator;

 public CircleProgressView(Context context) {
  this(context, null);
 }

 public CircleProgressView(Context context, @Nullable AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public CircleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init(context, attrs);
 }

 private void init(Context context, AttributeSet attrs) {
  TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
  locationStart = typedArray.getInt(R.styleable.CircleProgressView_location_start, 1);
  mProgressWidth = typedArray.getDimension(R.styleable.CircleProgressView_progress_width, dp2px(context, 4));
  mProgressColor = typedArray.getColor(R.styleable.CircleProgressView_progress_color, mProgressColor);
  typedArray.recycle();

  //背景圆弧
  mBgPaint = new Paint();
  mBgPaint.setAntiAlias(true);
  mBgPaint.setStrokeWidth(mProgressWidth);
  mBgPaint.setStyle(Paint.Style.STROKE);
  mBgPaint.setColor(Color.parseColor("#eaecf0"));
  mBgPaint.setStrokeCap(Paint.Cap.ROUND);

  //进度圆弧
  mProgressPaint = new Paint();
  mProgressPaint.setAntiAlias(true);
  mProgressPaint.setStyle(Paint.Style.STROKE);
  mProgressPaint.setStrokeWidth(mProgressWidth);
  mProgressPaint.setColor(mProgressColor);
  mProgressPaint.setStrokeCap(Paint.Cap.ROUND);

  //进度条起始角度
  if (locationStart == 1) {//左
   startAngle = -180;
  } else if (locationStart == 2) {//上
   startAngle = -90;
  } else if (locationStart == 3) {//右
   startAngle = 0;
  } else if (locationStart == 4) {//下
   startAngle = 90;
  }
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int width = MeasureSpec.getSize(widthMeasureSpec);
  int height = MeasureSpec.getSize(heightMeasureSpec);
  int size = width < height ? width : height;
  setMeasuredDimension(size, size);
 }

 /**
  * oval // 绘制范围
  * startAngle // 开始角度
  * sweepAngle // 扫过角度
  * useCenter // 是否使用中心
  */
 @Override
 protected void onDraw(Canvas canvas) {
  //绘制背景圆弧
  RectF rectF = new RectF(mProgressWidth / 2, mProgressWidth / 2, getWidth() - mProgressWidth / 2, getHeight() - mProgressWidth / 2);
  canvas.drawArc(rectF, 0, 360, false, mBgPaint);

  //绘制当前进度
  float sweepAngle = 360 * mCurrent / 100;
  canvas.drawArc(rectF, startAngle, sweepAngle, false, mProgressPaint);
 }

 public int getCurrent() {
  return mCurrent;
 }

 /**
  * 设置进度
  *
  * @param current
  */
 public void setCurrent(int current) {
  mCurrent = current;
  invalidate();
 }

 private int tCurrent = -1;

 /**
  * 动画效果
  *
  * @param current 精度条进度:0-100
  * @param duration 动画时间
  */
 public void startAnimProgress(int current, int duration) {
  mAnimator = ValueAnimator.ofInt(0, current);
  mAnimator.setDuration(duration);
  mAnimator.setInterpolator(new LinearInterpolator());
  mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    int current = (int) animation.getAnimatedValue();
    if (tCurrent != current) {
     tCurrent = current;
     setCurrent(current);
     if (mOnAnimProgressListener != null)
      mOnAnimProgressListener.valueUpdate(current);
    }
   }
  });
  mAnimator.start();
 }

 public interface OnAnimProgressListener {
  void valueUpdate(int progress);
 }

 private OnAnimProgressListener mOnAnimProgressListener;

 /**
  * 监听进度条进度
  *
  * @param onAnimProgressListener
  */
 public void setOnAnimProgressListener(OnAnimProgressListener onAnimProgressListener) {
  mOnAnimProgressListener = onAnimProgressListener;
 }

 public void destroy() {
  if (mAnimator != null) {
   mAnimator.cancel();
  }
 }

 public static int dp2px(Context context, float dpValue) {
  final float scale = context.getResources().getDisplayMetrics().density;
  return (int) (dpValue * scale + 0.5f);
 }
}

代码就这么些,接下来我们测算一下

package com.sample.circleprogressview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.sample.circleprogressview.widget.CircleProgressView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

 private CircleProgressView circle_progress;
 private TextView tv_progress;
 private Button btn_start;
 private Button btn_reset;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  btn_start = (Button) findViewById(R.id.btn_start);
  btn_reset = (Button) findViewById(R.id.btn_reset);
  circle_progress = (CircleProgressView) findViewById(R.id.circle_progress);
  tv_progress = (TextView) findViewById(R.id.tv_progress);

  btn_start.setOnClickListener(this);
  btn_reset.setOnClickListener(this);
 }

 @Override
 public void onClick(View v) {
  switch (v.getId()) {
   case R.id.btn_start:
    //开锁执行动画效果
    circle_progress.startAnimProgress(50, 1200);
    //监听进度条进度
    circle_progress.setOnAnimProgressListener(new CircleProgressView.OnAnimProgressListener() {
     @Override
     public void valueUpdate(int progress) {
      tv_progress.setText(String.valueOf(progress));
     }
    });
    break;
   case R.id.btn_reset:
    circle_progress.setCurrent(0);
    tv_progress.setText("0");
    break;
  }
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();
  if (circle_progress != null) {
   circle_progress.destroy();
  }
 }
}

源码:下载地址

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

相关文章

  • 常见Android编译优化问题梳理总结

    常见Android编译优化问题梳理总结

    这篇文章主要介绍了常见Android编译优化问题梳理总结,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-08-08
  • 关于Android多渠道打包问题看这一篇就够了

    关于Android多渠道打包问题看这一篇就够了

    这篇文章主要介绍了关于Android程序的多渠道打包方法,还不会的同学快进来学习下吧,建议收藏以防迷路
    2021-08-08
  • Android UI开发 View自绘控件 分享

    Android UI开发 View自绘控件 分享

    Android UI开发 View自绘控件 分享,需要的朋友可以参考一下
    2013-05-05
  • Android Camera1实现预览框显示

    Android Camera1实现预览框显示

    这篇文章主要为大家详细介绍了Android Camera1实现预览框显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • android查看网络图片的实现方法

    android查看网络图片的实现方法

    这篇文章主要为大家详细介绍了android查看网络图片的实现方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • Android应用 坐标系详细介绍

    Android应用 坐标系详细介绍

    这篇文章主要介绍了 Android 坐标系的相关资料,本文对Android 坐标系的知识做了详细解读,需要的朋友可以参考下
    2016-11-11
  • Android自定义图片集合

    Android自定义图片集合

    这篇文章主要为大家分享了内容相当丰富的Android自定义图片集合,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • 轻松实现Android3D效果通俗易懂

    轻松实现Android3D效果通俗易懂

    前几天有粉丝要求计蒙写一个3d效果的简单教程,其实这个在Android官方demo中是有的,可能对于新手而言看不太明白,于是根据本人自己的理解来写一个教程,并改成粉丝要求的样子
    2021-08-08
  • Android获取双卡双待手机的SIM卡信息示例代码

    Android获取双卡双待手机的SIM卡信息示例代码

    这篇文章主要给大家介绍了关于Android获取双卡双待手机的SIM卡信息的相关资料,文中通过示例代码介绍的非常详细,对各位Android开发者们具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-11-11
  • 详谈android界面之间数据的传递

    详谈android界面之间数据的传递

    下面小编就为大家带来一篇详谈android界面之间数据的传递。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06

最新评论