Android自定義view漸變圓形動(dòng)畫(huà)
本文實(shí)例為大家分享了Android自定義view漸變圓形動(dòng)畫(huà)的具體代碼,供大家參考,具體內(nèi)容如下
直接上效果圖

自定義屬性
attrs.xml文件
<resources>
<declare-styleable name="ProgressRing">
<!--進(jìn)度起始色-->
<attr name="pr_progress_start_color" format="color" />
<!--進(jìn)度結(jié)束色-->
<attr name="pr_progress_end_color" format="color" />
<!--背景起始色-->
<attr name="pr_bg_start_color" format="color" />
<!--背景中間色-->
<attr name="pr_bg_mid_color" format="color" />
<!--背景結(jié)束色-->
<attr name="pr_bg_end_color" format="color" />
<!--進(jìn)度值 介于0-100-->
<attr name="pr_progress" format="integer" />
<!--進(jìn)度寬度-->
<attr name="pr_progress_width" format="dimension" />
<!--起始角度-->
<attr name="pr_start_angle" format="integer" />
<!--掃過(guò)的角度-->
<attr name="pr_sweep_angle" format="integer" />
<!--是否顯示動(dòng)畫(huà)-->
<attr name="pr_show_anim" format="boolean" />
</declare-styleable>
</resources>
創(chuàng)建一個(gè)類(lèi) ProgressRing繼承自 view
public class ProgressRing extends View {
private int progressStartColor;
private int progressEndColor;
private int bgStartColor;
private int bgMidColor;
private int bgEndColor;
private int progress;
private float progressWidth;
private int startAngle;
private int sweepAngle;
private boolean showAnim;
private int mMeasureHeight;
private int mMeasureWidth;
private Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
private Paint progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG);
private RectF pRectF;
private float unitAngle;
private int curProgress = 0;
public ProgressRing(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ProgressRing);
progressStartColor = ta.getColor(R.styleable.ProgressRing_pr_progress_start_color, Color.YELLOW);
progressEndColor = ta.getColor(R.styleable.ProgressRing_pr_progress_end_color, progressStartColor);
bgStartColor = ta.getColor(R.styleable.ProgressRing_pr_bg_start_color, Color.LTGRAY);
bgMidColor = ta.getColor(R.styleable.ProgressRing_pr_bg_mid_color, bgStartColor);
bgEndColor = ta.getColor(R.styleable.ProgressRing_pr_bg_end_color, bgStartColor);
progress = ta.getInt(R.styleable.ProgressRing_pr_progress, 0);
progressWidth = ta.getDimension(R.styleable.ProgressRing_pr_progress_width, 8f);
startAngle = ta.getInt(R.styleable.ProgressRing_pr_start_angle, 150);
sweepAngle = ta.getInt(R.styleable.ProgressRing_pr_sweep_angle, 240);
showAnim = ta.getBoolean(R.styleable.ProgressRing_pr_show_anim, true);
ta.recycle();
unitAngle = (float) (sweepAngle / 100.0);
bgPaint.setStyle(Paint.Style.STROKE);
bgPaint.setStrokeCap(Paint.Cap.ROUND);
bgPaint.setStrokeWidth(progressWidth);
progressPaint.setStyle(Paint.Style.STROKE);
progressPaint.setStrokeCap(Paint.Cap.ROUND);
progressPaint.setStrokeWidth(progressWidth);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
/*for (int i = 0, end = (int) (progress * unitAngle); i <= end; i++) {
progressPaint.setColor(getGradient(i / (float) end, progressStartColor, progressEndColor));
canvas.drawArc(pRectF,
startAngle + i,
1,
false,
progressPaint);
}*/
if (!showAnim) {
curProgress = progress;
}
drawBg(canvas);
drawProgress(canvas);
if (curProgress < progress) {
curProgress++;
postInvalidate();
}
}
// 只需要畫(huà)進(jìn)度之外的背景即可
private void drawBg(Canvas canvas) {
float halfSweep = sweepAngle / 2;
for (int i = sweepAngle, st = (int) (curProgress * unitAngle); i > st; --i) {
if (i - halfSweep > 0) {
bgPaint.setColor(getGradient((i - halfSweep) / halfSweep, bgMidColor, bgEndColor));
} else {
bgPaint.setColor(getGradient((halfSweep - i) / halfSweep, bgMidColor, bgStartColor));
}
canvas.drawArc(pRectF,
startAngle + i,
1,
false,
bgPaint);
}
}
private void drawProgress(Canvas canvas) {
for (int i = 0, end = (int) (curProgress * unitAngle); i <= end; i++) {
progressPaint.setColor(getGradient(i / (float) end, progressStartColor, progressEndColor));
canvas.drawArc(pRectF,
startAngle + i,
1,
false,
progressPaint);
}
}
public void setProgress(@IntRange(from = 0, to = 100) int progress) {
this.progress = progress;
invalidate();
}
public int getProgress() {
return progress;
}
public int getGradient(float fraction, int startColor, int endColor) {
if (fraction > 1) fraction = 1;
int alphaStart = Color.alpha(startColor);
int redStart = Color.red(startColor);
int blueStart = Color.blue(startColor);
int greenStart = Color.green(startColor);
int alphaEnd = Color.alpha(endColor);
int redEnd = Color.red(endColor);
int blueEnd = Color.blue(endColor);
int greenEnd = Color.green(endColor);
int alphaDifference = alphaEnd - alphaStart;
int redDifference = redEnd - redStart;
int blueDifference = blueEnd - blueStart;
int greenDifference = greenEnd - greenStart;
int alphaCurrent = (int) (alphaStart + fraction * alphaDifference);
int redCurrent = (int) (redStart + fraction * redDifference);
int blueCurrent = (int) (blueStart + fraction * blueDifference);
int greenCurrent = (int) (greenStart + fraction * greenDifference);
return Color.argb(alphaCurrent, redCurrent, greenCurrent, blueCurrent);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mMeasureWidth = getMeasuredWidth();
mMeasureHeight = getMeasuredHeight();
if (pRectF == null) {
float halfProgressWidth = progressWidth / 2;
pRectF = new RectF(halfProgressWidth + getPaddingLeft(),
halfProgressWidth + getPaddingTop(),
mMeasureWidth - halfProgressWidth - getPaddingRight(),
mMeasureHeight - halfProgressWidth - getPaddingBottom());
}
}
}
xml布局
<myCircle.ProgressRing android:layout_width="320dp" android:layout_height="320dp" android:layout_gravity="center_horizontal" app:pr_bg_end_color="#00ffffff" app:pr_bg_mid_color="#CCCCCC" app:pr_bg_start_color="#00ffffff" app:pr_progress="70" app:pr_progress_end_color="#F78930" app:pr_progress_start_color="#00ffffff" app:pr_progress_width="40dp" />
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android 軟鍵盤(pán)彈出隱藏?cái)D壓界面等各種問(wèn)題小結(jié)
這篇文章主要介紹了Android 軟鍵盤(pán)彈出隱藏?cái)D壓界面等各種問(wèn)題的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-11-11
解決VSCode調(diào)試react-native android項(xiàng)目錯(cuò)誤問(wèn)題
這篇文章主要介紹了VSCode調(diào)試react-native android項(xiàng)目錯(cuò)誤解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Android實(shí)現(xiàn)可折疊式標(biāo)題欄
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可折疊式標(biāo)題欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
Android ExpandableRecyclerView使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Android ExpandableRecyclerView的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
Android自定義實(shí)現(xiàn)可滑動(dòng)按鈕
這篇文章主要為大家詳細(xì)介紹了Android自定義實(shí)現(xiàn)可滑動(dòng)的按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
Android簡(jiǎn)單實(shí)現(xiàn)畫(huà)圖功能
這篇文章主要為大家詳細(xì)介紹了Android簡(jiǎn)單實(shí)現(xiàn)畫(huà)圖功能的方法,以及實(shí)現(xiàn)過(guò)程中遇到的問(wèn)題,感興趣的小伙伴們可以參考一下2016-03-03
Android開(kāi)發(fā)中Toast顯示消息的方法小結(jié)
這篇文章主要介紹了Android開(kāi)發(fā)中Toast顯示消息的方法,結(jié)合實(shí)例形式總結(jié)分析了Toast的功能、創(chuàng)建Toast對(duì)象及調(diào)用相關(guān)函數(shù)顯示消息提示框的操作技巧,需要的朋友可以參考下2016-10-10
Android自動(dòng)填充短信驗(yàn)證碼功能(demo)
在項(xiàng)目開(kāi)發(fā)中為了給用戶(hù)帶來(lái)極好的體驗(yàn)效果,通常需要實(shí)現(xiàn)驗(yàn)證碼的自動(dòng)填充功能,怎么實(shí)現(xiàn)呢?今天小編給大家分享Android自動(dòng)填充短信驗(yàn)證碼功能的實(shí)現(xiàn)方法,需要的朋友參考下吧2017-02-02
Android樣式的開(kāi)發(fā):layer-list實(shí)例詳解
本文主要介紹Android樣式開(kāi)發(fā)layer-list,這里整理了詳細(xì)的資料,及簡(jiǎn)單示例代碼有興趣的小伙伴可以參考下2016-09-09
在Android Studio中Parcelable插件的簡(jiǎn)單使用教程
下面小編就為大家分享一篇在Android Studio中Parcelable插件的簡(jiǎn)單使用教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-11-11

