Android自定義View圓形進(jìn)度條控件(三)
繼續(xù)練習(xí)自定義View,這次帶來(lái)的圓形進(jìn)度條控件與之前的圓形百分比控件大同小異,這次涉及到了漸變渲染以及畫(huà)布旋轉(zhuǎn)等知識(shí)點(diǎn),效果如下:

雖然步驟類(lèi)似,但是我還是要寫(xiě),畢竟基礎(chǔ)的東西就是要多練
1、在res/values文件夾下新建attrs.xml文件,編寫(xiě)自定義屬性:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CircleProgressView"> <!-- 弧線寬度 --> <attr name="arcWidth" format="dimension" /> <!-- 刻度個(gè)數(shù) --> <attr name="scaleCount" format="integer" /> <!-- 漸變起始顏色 --> <attr name="startColor" format="color" /> <!-- 漸變終止顏色 --> <attr name="endColor" format="color" /> <!-- 標(biāo)簽說(shuō)明文本 --> <attr name="labelText" format="string" /> <!-- 文本顏色 --> <attr name="textColor" format="color" /> <!-- 百分比文本字體大小 --> <attr name="progressTextSize" format="dimension" /> <!-- 標(biāo)簽說(shuō)明字體大小 --> <attr name="labelTextSize" format="dimension" /> </declare-styleable> </resources>
2、新建CircleProgressView繼承View,重寫(xiě)構(gòu)造方法:
public CircleProgressView(Context context) {
this(context, null);
}
public CircleProgressView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleProgressView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
3、在第三個(gè)構(gòu)造方法中獲取自定義屬性的值:
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressView, defStyleAttr, 0);
mArcWidth = ta.getDimension(R.styleable.CircleProgressView_arcWidth, DensityUtils.dp2px(context, 8));
mScaleCount = ta.getInteger(R.styleable.CircleProgressView_scaleCount, 24);
mStartColor = ta.getColor(R.styleable.CircleProgressView_startColor, Color.parseColor("#3FC199"));
mEndColor = ta.getColor(R.styleable.CircleProgressView_endColor, Color.parseColor("#3294C1"));
mColorArray = new int[]{mStartColor, mEndColor};
mLabelText = ta.getString(R.styleable.CircleProgressView_labelText);
mTextColor = ta.getColor(R.styleable.CircleProgressView_textColor, Color.parseColor("#4F5F6F"));
mProgressTextSize = ta.getDimension(R.styleable.CircleProgressView_progressTextSize, 160);
mLabelTextSize = ta.getDimension(R.styleable.CircleProgressView_labelTextSize, 64);
ta.recycle();
4、創(chuàng)建畫(huà)圖所使用的對(duì)象,如Paint、Rect、RectF:
mArcBackPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mArcBackPaint.setStyle(Paint.Style.STROKE); mArcBackPaint.setStrokeWidth(mArcWidth); mArcBackPaint.setColor(Color.LTGRAY); mArcForePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mArcForePaint.setStyle(Paint.Style.STROKE); mArcForePaint.setStrokeWidth(mArcWidth); mArcRectF = new RectF(); mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLinePaint.setStyle(Paint.Style.STROKE); mLinePaint.setColor(Color.WHITE); mLinePaint.setStrokeWidth(DensityUtils.dp2px(context, 2)); mProgressTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mProgressTextPaint.setStyle(Paint.Style.FILL); mProgressTextPaint.setColor(mTextColor); mProgressTextPaint.setTextSize(mProgressTextSize); mLabelTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mLabelTextPaint.setStyle(Paint.Style.FILL); mLabelTextPaint.setColor(mTextColor); mLabelTextPaint.setTextSize(mLabelTextSize); mTextRect = new Rect();
5、重寫(xiě)onMeasure()方法,計(jì)算自定義View的寬高:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measuredDimension(widthMeasureSpec), measuredDimension(heightMeasureSpec));
}
private int measuredDimension(int measureSpec) {
int result;
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 800;
if (mode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
6、重寫(xiě)onDraw()方法,繪制圓弧、刻度線和百分比文本、標(biāo)簽說(shuō)明文本,注意坐標(biāo)的計(jì)算:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mArcRectF.set(mArcWidth / 2, mArcWidth / 2, getWidth() - mArcWidth / 2, getHeight() - mArcWidth / 2);
//畫(huà)背景弧線
canvas.drawArc(mArcRectF, -90, 360, false, mArcBackPaint);
//設(shè)置漸變渲染
LinearGradient linearGradient = new LinearGradient(getWidth() / 2, 0, getWidth() / 2, getHeight(), mColorArray, null, Shader.TileMode.CLAMP);
mArcForePaint.setShader(linearGradient);
//畫(huà)百分比值弧線
canvas.drawArc(mArcRectF, -90, mSweepAngle, false, mArcForePaint);
//畫(huà)刻度線
for (int i = 0; i < mScaleCount; i++) {
canvas.drawLine(getWidth() / 2, 0, getWidth() / 2, mArcWidth, mLinePaint);
//旋轉(zhuǎn)畫(huà)布
canvas.rotate(360 / mScaleCount, getWidth() / 2, getHeight() / 2);
}
//畫(huà)百分比文本
String progressText = mProgress + "%";
mProgressTextPaint.getTextBounds(progressText, 0, progressText.length(), mTextRect);
float progressTextWidth = mTextRect.width();
float progressTextHeight = mTextRect.height();
canvas.drawText(progressText, getWidth() / 2 - progressTextWidth / 2,
getHeight() / 2 + progressTextHeight / 2, mProgressTextPaint);
//畫(huà)標(biāo)簽說(shuō)明文本
mLabelTextPaint.getTextBounds(mLabelText, 0, mLabelText.length(), mTextRect);
canvas.drawText(mLabelText, getWidth() / 2 - mTextRect.width() / 2,
getHeight() / 2 - progressTextHeight / 2 - mTextRect.height(), mLabelTextPaint);
}
7、暴露一個(gè)動(dòng)態(tài)設(shè)置百分比的方法:
public void setProgress(float progress) {
Log.e("--> ", progress + "");
ValueAnimator anim = ValueAnimator.ofFloat(mProgress, progress);
anim.setDuration((long) (Math.abs(mProgress - progress) * 20));
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mProgress = (float) animation.getAnimatedValue();
mSweepAngle = mProgress * 360 / 100;
mProgress = (float) (Math.round(mProgress * 10)) / 10;//四舍五入保留到小數(shù)點(diǎn)后兩位
invalidate();
}
});
anim.start();
}
8、在activity_main.xml布局文件中使用該View:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cpv="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <com.monkey.circleprogressview.CircleProgressView android:id="@+id/circle_progress_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" cpv:arcWidth="8dp" cpv:endColor="#126b94" cpv:labelText="學(xué)習(xí)進(jìn)度" cpv:labelTextSize="20sp" cpv:progressTextSize="55sp" cpv:scaleCount="24" cpv:startColor="#12d699" cpv:textColor="#4F5F6F" /> </RelativeLayout>
9、在MainActivity中設(shè)置監(jiān)聽(tīng),傳入百分比:
final CircleProgressView view = (CircleProgressView) findViewById(R.id.circle_progress_view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
float progress = (float) (Math.random() * 100);
view.setProgress(progress);
}
});
代碼下載地址
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android自定義View繪制的方法及過(guò)程(二)
- Android自定義View實(shí)現(xiàn)飄動(dòng)的葉子效果(三)
- Android自定義View實(shí)現(xiàn)葉子飄動(dòng)旋轉(zhuǎn)效果(四)
- Android自定義View實(shí)現(xiàn)多片葉子旋轉(zhuǎn)滑動(dòng)(五)
- Android自定義View葉子旋轉(zhuǎn)完整版(六)
- Android自定義View簡(jiǎn)易折線圖控件(二)
- Android 自定義View的使用介紹
- Android自定義View設(shè)定到FrameLayout布局中實(shí)現(xiàn)多組件顯示的方法 分享
- Android自定義View實(shí)現(xiàn)廣告信息上下滾動(dòng)效果
- Android自定義View中Paint、Rect、Canvas介紹(一)
相關(guān)文章
Android天氣預(yù)報(bào)app改進(jìn)版
這篇文章主要為大家詳細(xì)介紹了改進(jìn)版的Android天氣預(yù)報(bào)app,內(nèi)容更加充實(shí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-07-07
android端使用openCV實(shí)現(xiàn)車(chē)牌檢測(cè)
這篇文章主要為大家詳細(xì)介紹了android端使用openCV實(shí)現(xiàn)車(chē)牌檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
android開(kāi)發(fā)設(shè)計(jì)模式之——單例模式詳解
本篇文章主要介紹了android開(kāi)發(fā)設(shè)計(jì)模式之——單例模式詳解,具有一定的參考價(jià)值,有需要的可以了解一下。2016-11-11
Android簡(jiǎn)單封裝一個(gè)MVP基類(lèi)流程詳解
MVP是從經(jīng)典的模式MVC演變而來(lái),它們的基本思想有相通的地方:Controller/Presenter負(fù)責(zé)邏輯的處理,Model提供數(shù)據(jù),View負(fù)責(zé)顯示。下面這篇文章主要給大家介紹了關(guān)于Android從實(shí)現(xiàn)到封裝MVP的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧2023-03-03
Android中EditText實(shí)現(xiàn)不可編輯解決辦法
這篇文章主要介紹了Android中EditText實(shí)現(xiàn)不可編輯解決辦法,需要的朋友可以參考下2014-12-12
Android開(kāi)發(fā)筆記之:消息循環(huán)與Looper的詳解
本篇文章是對(duì)Android中消息循環(huán)與Looper的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
Android使用CountDownTimer類(lèi)實(shí)現(xiàn)倒計(jì)時(shí)鬧鐘
這篇文章主要為大家詳細(xì)介紹了Android使用CountDownTimer類(lèi)實(shí)現(xiàn)倒計(jì)時(shí)鬧鐘,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01

