Android自定義帶動畫效果的圓形ProgressBar
本文實例為大家分享了Android自定義帶動畫效果的圓形ProgressBar,供大家參考,具體內(nèi)容如下
最近有個需求顯示進度,尾部還要有一標(biāo)示,像下邊這樣

使用自定義View的方式實現(xiàn),代碼如下,很簡單注釋的很清楚
文章最后我們拓展一下功能,實現(xiàn)一個帶動畫效果的進度條
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;
/**
* 內(nèi)圓的顏色
*/
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);
//內(nèi)圓
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(); //平移畫布之前保存之前畫的
//畫進度終點的小球,旋轉(zhuǎn)畫布的方式實現(xiàn)
mPaint.setStyle(Paint.Style.FILL);
//將畫布坐標(biāo)原點移動至圓心
canvas.translate(center, center);
//旋轉(zhuǎn)和進度相同的角度,因為進度是從-90度開始的所以-90度
canvas.rotate(mAngle - 90);
//同理從圓心出發(fā)直接將原點平移至要畫小球的位置
canvas.translate(radius, 0);
canvas.drawCircle(0, 0, roundWidth, mPaint);
//畫完之后恢復(fù)畫布坐標(biāo)
canvas.restore();
//畫文字將坐標(biāo)平移至圓心
canvas.translate(center, center);
mPaint.setStrokeWidth(0);
mPaint.setColor(textColor);
if (isBold) {
//字體加粗
mPaint.setTypeface(Typeface.DEFAULT_BOLD);
}
if (TextUtils.isEmpty(mText)) {
mText = mProgress + "%";
}
//動態(tài)設(shè)置文字長為圓半徑,計算字體大小
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;
}
/**
* 設(shè)置進度
*
* @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;
}
/**
* 設(shè)置文本
*
* @param mText
*/
public void setmText(String mText) {
this.mText = mText;
}
/**
* 設(shè)置帶動畫的進度
* @param p
*/
public void setAnimProgress(int p) {
if (p > MAX_PROGRESS) {
mProgress = MAX_PROGRESS;
} else {
mProgress = p;
}
//設(shè)置屬性動畫
ValueAnimator valueAnimator = new ValueAnimator().ofInt(0, p);
//動畫從快到慢
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(3000);
//監(jiān)聽值的變化
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中設(shè)置進度,顯示文字
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)設(shè)置動畫效果:
/**
* 設(shè)置帶動畫的進度
* @param p
*/
public void setAnimProgress(int p) {
if (p > MAX_PROGRESS) {
mProgress = MAX_PROGRESS;
} else {
mProgress = p;
}
//設(shè)置屬性動畫
ValueAnimator valueAnimator = new ValueAnimator().ofInt(0, p);
//動畫從快到慢
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(3000);
//監(jiān)聽值的變化
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中調(diào)用這個方法
circleProgressBar.setAnimProgress(65);
效果如下

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實現(xiàn)動畫效果的自定義下拉菜單功能
- Android自定義view仿QQ的Tab按鈕動畫效果(示例代碼)
- Android自定義view之圍棋動畫效果的實現(xiàn)
- Android動畫系列之屬性動畫的基本使用教程
- android實現(xiàn)加載動畫對話框
- Android動畫系列之幀動畫和補間動畫的示例代碼
- Android實現(xiàn)長按圓環(huán)動畫View效果的思路代碼
- android自定義環(huán)形統(tǒng)計圖動畫
- android實現(xiàn)截圖并動畫消失效果的思路詳解
- Android 自定義加載動畫Dialog彈窗效果的示例代碼
- Android實現(xiàn)美團外賣底部導(dǎo)航欄動畫
- Android 使用cos和sin繪制復(fù)合曲線動畫
相關(guān)文章
Android中不支持動態(tài)申請權(quán)限的原因
這篇文章主要介紹了Android中不支持動態(tài)申請權(quán)限的原因,本文列舉了幾個不支持動態(tài)申請權(quán)限的原因,需要的朋友可以參考下2015-01-01
Android開發(fā)中使用mms模塊收發(fā)單卡和雙卡短信的教程
這篇文章主要介紹了Android開發(fā)中使用mms模塊收發(fā)單卡和雙卡短信的教程,文中舉了MOTO XT800手機(估計已經(jīng)落伍很久了--)的例子來說明如何解決雙卡雙待時的短信異常問題,需要的朋友可以參考下2016-02-02
GridView基于pulltorefresh實現(xiàn)下拉刷新 上拉加載更多功能(推薦)
原理和listview一樣 ,都是重寫Android原生控件。下面小編通過實例代碼給大家分享GridView基于pulltorefresh實現(xiàn)下拉刷新 上拉加載更多功能,非常不錯,一起看看吧2016-11-11
Android 開發(fā)實現(xiàn)EditText 光標(biāo)居右顯示
這篇文章主要介紹了Android 開發(fā)實現(xiàn)EditText 光標(biāo)居右顯示的相關(guān)資料,需要的朋友可以參考下2017-02-02

