Android自定义带动画效果的圆形ProgressBar

本文实例为大家分享了Android自定义带动画效果的圆形ProgressBar,供大家参考,具体内容如下

最近有个需求显示进度,尾部还要有一标示,像下边这样

使用自定义View的方式实现,代码如下,很简单注释的很清楚

文章最后我们拓展一下功能,实现一个带动画效果的进度条

package com.example.fwc.allexample.progressbar;

import android.animation.ValueAnimator;

import android.annotation.TargetApi;

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.graphics.Typeface;

import android.os.Handler;

import android.os.Message;

import android.text.TextUtils;

import android.util.AttributeSet;

import android.util.Log;

import android.view.View;

import android.view.animation.DecelerateInterpolator;

import com.example.fwc.allexample.R;

/**

* Created by fwc on 2016/7/6.

*/

public class CircleProgressBar extends View {

private Context mContext;

private Paint mPaint;

private int mProgress = 0;

private static int MAX_PROGRESS = 100;

/**

* 弧度

*/

private int mAngle;

/**

* 中间的文字

*/

private String mText;

/**

* 外圆颜色

*/

private int outRoundColor;

/**

* 内圆的颜色

*/

private int inRoundColor;

/**

* 线的宽度

*/

private int roundWidth;

private int style;

/**

* 字体颜色

*/

private int textColor;

/**

* 字体大小

*/

private float textSize;

/**

* 字体是否加粗

*/

private boolean isBold;

/**

* 进度条颜色

*/

private int progressBarColor;

public CircleProgressBar(Context context) {

this(context, null);

}

public CircleProgressBar(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

mContext = context;

init(attrs);

}

@TargetApi(21)

public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {

super(context, attrs, defStyleAttr, defStyleRes);

mContext = context;

init(attrs);

}

/**

* 解析自定义属性

*

* @param attrs

*/

public void init(AttributeSet attrs) {

mPaint = new Paint();

TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);

outRoundColor = typedArray.getColor(R.styleable.CircleProgressBar_outCircleColor, getResources().getColor(R.color.colorPrimary));

inRoundColor = typedArray.getColor(R.styleable.CircleProgressBar_inCircleColor, getResources().getColor(R.color.colorPrimaryDark));

progressBarColor = typedArray.getColor(R.styleable.CircleProgressBar_progressColor, getResources().getColor(R.color.colorAccent));

isBold = typedArray.getBoolean(R.styleable.CircleProgressBar_textBold, false);

textColor = typedArray.getColor(R.styleable.CircleProgressBar_textColor, Color.BLACK);

roundWidth = typedArray.getDimensionPixelOffset(R.styleable.CircleProgressBar_lineWidth, 20);

typedArray.recycle();

}

@Override

protected void onDraw(Canvas canvas) {

/**

* 画外圆

*/

super.onDraw(canvas);

int center = getWidth() / 2; //圆心

int radius = (center - roundWidth / 2); //半径

mPaint.setColor(outRoundColor); //外圆颜色

mPaint.setStrokeWidth(roundWidth); //线的宽度

mPaint.setStyle(Paint.Style.STROKE); //空心圆

mPaint.setAntiAlias(true); //消除锯齿

canvas.drawCircle(center, center, radius, mPaint);

//内圆

mPaint.setColor(inRoundColor);

radius = radius - roundWidth;

canvas.drawCircle(center, center, radius, mPaint);

//画进度是一个弧线

mPaint.setColor(progressBarColor);

RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);//圆弧范围的外接矩形

canvas.drawArc(rectF, -90, mAngle, false, mPaint);

canvas.save(); //平移画布之前保存之前画的

//画进度终点的小球,旋转画布的方式实现

mPaint.setStyle(Paint.Style.FILL);

//将画布坐标原点移动至圆心

canvas.translate(center, center);

//旋转和进度相同的角度,因为进度是从-90度开始的所以-90度

canvas.rotate(mAngle - 90);

//同理从圆心出发直接将原点平移至要画小球的位置

canvas.translate(radius, 0);

canvas.drawCircle(0, 0, roundWidth, mPaint);

//画完之后恢复画布坐标

canvas.restore();

//画文字将坐标平移至圆心

canvas.translate(center, center);

mPaint.setStrokeWidth(0);

mPaint.setColor(textColor);

if (isBold) {

//字体加粗

mPaint.setTypeface(Typeface.DEFAULT_BOLD);

}

if (TextUtils.isEmpty(mText)) {

mText = mProgress + "%";

}

//动态设置文字长为圆半径,计算字体大小

float textLength = mText.length();

textSize = radius / textLength;

mPaint.setTextSize(textSize);

//将文字画到中间

float textWidth = mPaint.measureText(mText);

canvas.drawText(mText, -textWidth / 2, textSize / 2, mPaint);

}

public int getmProgress() {

return mProgress;

}

/**

* 设置进度

*

* @return

*/

public void setmProgress(int p) {

if (p > MAX_PROGRESS) {

mProgress = MAX_PROGRESS;

mAngle = 360;

} else {

mProgress = p;

mAngle = 360 * p / MAX_PROGRESS;

}

}

public String getmText() {

return mText;

}

/**

* 设置文本

*

* @param mText

*/

public void setmText(String mText) {

this.mText = mText;

}

/**

* 设置带动画的进度

* @param p

*/

public void setAnimProgress(int p) {

if (p > MAX_PROGRESS) {

mProgress = MAX_PROGRESS;

} else {

mProgress = p;

}

//设置属性动画

ValueAnimator valueAnimator = new ValueAnimator().ofInt(0, p);

//动画从快到慢

valueAnimator.setInterpolator(new DecelerateInterpolator());

valueAnimator.setDuration(3000);

//监听值的变化

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

int currentV = (Integer) animation.getAnimatedValue();

Log.e("fwc", "current" + currentV);

mAngle = 360 * currentV / MAX_PROGRESS;

mText = currentV + "%";

invalidate();

}

});

valueAnimator.start();

}

}

自定义属性

<declare-styleable name="CircleProgressBar">

<attr name="outCircleColor" format="color"></attr>

<attr name="inCircleColor" format="color"></attr>

<attr name="progressColor" format="color"></attr>

<attr name="textColor" format="color"></attr>

<attr name="textBold" format="boolean"></attr>

<attr name="lineWidth" format="dimension"></attr>

</declare-styleable>

布局文件中使用

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

xmlns:my="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="com.example.fwc.allexample.progressbar.ProgressActivtiy">

<com.example.fwc.allexample.progressbar.CircleProgressBar

android:id="@+id/progress_bar"

android:layout_centerInParent="true"

android:layout_width="150dp"

android:layout_height="150dp"

my:inCircleColor="#DCDCDC"

my:outCircleColor="#F0F0F0"

my:progressColor="#50CE7B"

my:textBold="true"

my:textColor="#50CE7B"

my:lineWidth="5dp"

/>

</RelativeLayout>

activity中设置进度,显示文字

package com.example.fwc.allexample.progressbar;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import com.example.fwc.allexample.R;

public class ProgressActivtiy extends AppCompatActivity {

CircleProgressBar circleProgressBar;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_progress_activtiy);

circleProgressBar = (CircleProgressBar)findViewById(R.id.progress_bar);

circleProgressBar.setProgress(65);

circleProgressBar.setmText(circleProgressBar.getProgress()+"%");

}

}

效果图

拓展

拓展也很简单,加一个setAnimProgress(int p)设置动画效果:

/**

* 设置带动画的进度

* @param p

*/

public void setAnimProgress(int p) {

if (p > MAX_PROGRESS) {

mProgress = MAX_PROGRESS;

} else {

mProgress = p;

}

//设置属性动画

ValueAnimator valueAnimator = new ValueAnimator().ofInt(0, p);

//动画从快到慢

valueAnimator.setInterpolator(new DecelerateInterpolator());

valueAnimator.setDuration(3000);

//监听值的变化

valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

@Override

public void onAnimationUpdate(ValueAnimator animation) {

int currentV = (Integer) animation.getAnimatedValue();

Log.e("fwc", "current" + currentV);

mAngle = 360 * currentV / MAX_PROGRESS;

mText = currentV + "%";

invalidate();

}

});

valueAnimator.start();

}

在activity中调用这个方法

circleProgressBar.setAnimProgress(65);

效果如下

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

以上是 Android自定义带动画效果的圆形ProgressBar 的全部内容, 来源链接: utcz.com/p/242727.html

回到顶部