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

使用自定義View的方式實現(xiàn),代碼如下,很簡單注釋的很清楚
文章最后我們拓展一下功能,實現(xiàn)一個帶動畫效果的進(jì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;
/**
* 進(jìn)度條顏色
*/
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);
//畫進(jìn)度是一個弧線
mPaint.setColor(progressBarColor);
RectF rectF = new RectF(center - radius, center - radius, center + radius, center + radius);//圓弧范圍的外接矩形
canvas.drawArc(rectF, -90, mAngle, false, mPaint);
canvas.save(); //平移畫布之前保存之前畫的
//畫進(jìn)度終點的小球,旋轉(zhuǎn)畫布的方式實現(xiàn)
mPaint.setStyle(Paint.Style.FILL);
//將畫布坐標(biāo)原點移動至圓心
canvas.translate(center, center);
//旋轉(zhuǎn)和進(jìn)度相同的角度,因為進(jì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è)置進(jìn)度
*
* @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è)置帶動畫的進(jìn)度
* @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è)置進(jìn)度,顯示文字
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è)置帶動畫的進(jìn)度
* @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)美團(tuán)外賣底部導(dǎo)航欄動畫
- Android 使用cos和sin繪制復(fù)合曲線動畫
相關(guān)文章
Android 優(yōu)化之卡頓優(yōu)化的實現(xiàn)
這篇文章主要介紹了Android 優(yōu)化之卡頓優(yōu)化的實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Android Flutter基于WebSocket實現(xiàn)即時通訊功能
WebSocket是一種在單個TCP連接上進(jìn)行全雙工通信的協(xié)議。本文將利用Flutter WebSocket實現(xiàn)即時通訊功能,文中示例代碼講解詳細(xì),感興趣的可以了解一下2022-03-03
Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法示例
這篇文章主要介紹了Android基于OpenGL在GLSurfaceView上繪制三角形及使用投影和相機(jī)視圖方法,結(jié)合實例形式分析了Android基于OpenGL的圖形繪制技巧,需要的朋友可以參考下2016-10-10
Android中WebView加載網(wǎng)頁設(shè)置進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android中WebView加載網(wǎng)頁設(shè)置進(jìn)度條的相關(guān)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
Android Drawerlayout實現(xiàn)側(cè)滑菜單效果
這篇文章主要為大家詳細(xì)介紹了Android Drawerlayout實現(xiàn)側(cè)滑菜單效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10
Android開發(fā)之搜索框SearchView用法示例
這篇文章主要介紹了Android開發(fā)之搜索框SearchView用法,結(jié)合實例形式分析了Android搜索框SearchView的基本功能、用法及相關(guān)操作注意事項,需要的朋友可以參考下2019-03-03
Android位圖(圖片)加載引入的內(nèi)存溢出問題詳細(xì)解析
Android在加載大背景圖或者大量圖片時,常常致使內(nèi)存溢出,下面這篇文章主要給大家介紹了關(guān)于Android位圖(圖片)加載引入的內(nèi)存溢出問題的相關(guān)資料,需要的朋友可以參考下2022-12-12

