溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android如何實(shí)現(xiàn)環(huán)形進(jìn)度條

發(fā)布時(shí)間:2021-04-17 09:46:17 來(lái)源:億速云 閱讀:794 作者:小新 欄目:移動(dòng)開發(fā)

這篇文章主要介紹Android如何實(shí)現(xiàn)環(huán)形進(jìn)度條,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!

一個(gè)通俗易懂的環(huán)形進(jìn)度條,可以定制顏色角度,監(jiān)聽進(jìn)度。

Android如何實(shí)現(xiàn)環(huán)形進(jìn)度條

定義一個(gè)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" />
  <!--加載進(jìn)度起始位置-->
  <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;


/**
 * 普通環(huán)形進(jìn)度條
 */
public class CircleProgressView extends View {
 private int mCurrent;//當(dāng)前進(jìn)度
 private Paint mBgPaint;//背景弧線paint
 private Paint mProgressPaint;//進(jìn)度Paint
 private float mProgressWidth;//進(jìn)度條寬度
 private int mProgressColor = Color.RED;//進(jìn)度條顏色
 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);

  //進(jìn)度圓弧
  mProgressPaint = new Paint();
  mProgressPaint.setAntiAlias(true);
  mProgressPaint.setStyle(Paint.Style.STROKE);
  mProgressPaint.setStrokeWidth(mProgressWidth);
  mProgressPaint.setColor(mProgressColor);
  mProgressPaint.setStrokeCap(Paint.Cap.ROUND);

  //進(jìn)度條起始角度
  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 // 掃過(guò)角度
  * 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);

  //繪制當(dāng)前進(jìn)度
  float sweepAngle = 360 * mCurrent / 100;
  canvas.drawArc(rectF, startAngle, sweepAngle, false, mProgressPaint);
 }

 public int getCurrent() {
  return mCurrent;
 }

 /**
  * 設(shè)置進(jìn)度
  *
  * @param current
  */
 public void setCurrent(int current) {
  mCurrent = current;
  invalidate();
 }

 private int tCurrent = -1;

 /**
  * 動(dòng)畫效果
  *
  * @param current 精度條進(jìn)度:0-100
  * @param duration 動(dòng)畫時(shí)間
  */
 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;

 /**
  * 監(jiān)聽進(jìn)度條進(jìn)度
  *
  * @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);
 }
}

代碼就這么些,接下來(lái)我們測(cè)算一下

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:
    //開鎖執(zhí)行動(dòng)畫效果
    circle_progress.startAnimProgress(50, 1200);
    //監(jiān)聽進(jìn)度條進(jìn)度
    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如何實(shí)現(xiàn)環(huán)形進(jìn)度條”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對(duì)大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI