CircleNumberProgressBar:顯示數字的圓形進度條
圓形的ProgressBar是經常使用的控制元件,能夠顯示當前的進度,但有時候可能還不夠直觀,原有控制元件顯示進度時並不能準確的知道當前進度是多少,又或是遇到專案需求需要在進度條中間加上數字顯示,嗯……專案需求,所以這個時候就需要自己對原有的ProgressBar進行改造了,自己動手,豐衣足食嘛!
在原有的ProgressBar的基礎上進行改造,那麼就新建一個類CircleNumberProgressBar,並讓其繼承ProgressBar,接著我們需要先定義好CircleNumberProgressBar需要的相關屬性
<declare-styleable name="CircleNumberProgressBar"> <!-- 圓的半徑 --> <attr name="cnpb_circle_radius" format="dimension"/> <!-- 進度條的寬度 --> <attr name="cnpb_bar_width" format="dimension" /> <!-- 達到的進度顏色 --> <attr name="cnpb_reach_color" format="color" /> <!-- 未達到的進度顏色 --> <attr name="cnpb_unreach_color" format="color" /> <!-- 文字大小 --> <attr name="cnpb_text_size" format="dimension" /> <!-- 文字顏色 --> <attr name="cnpb_text_color" format="color" /> <!-- 文字是否顯示 --> <attr name="cnpb_text_visibility" format="enum"> <enum name="invisible" value="0"/> <enum name="visible" value="1"/> </attr> <!-- 單位 --> <attr name="cnpb_unit" format="string"/> <!-- 單位是否顯示 --> <attr name="cnpb_unit_visibility" format="enum"> <enum name="invisible" value="0"/> <enum name="visible" value="1"/> </attr> </declare-styleable>
我們還可以定義一個設定CircleNumberProgressBar的Style的一個屬性
<attr name="styleCircleNumberProgressBar" format="reference" />
這樣可以方便我們在styles檔案中對CircleNumberProgressBar的屬性進行統一設定,例如
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="styleCircleNumberProgressBar">@style/CircleNumberProgressBarTheme</item> </style>
好了,定義並設定好屬性之後,就需要在程式碼檔案中對這些屬性進行取值設定了,在建構函式中使用TypedArray對申明的屬性進行取值,並在建構函式中對畫筆Paint進行一些相關屬性的設定
public CircleNumberProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleNumberProgressBar, defStyleAttr, R.style.CircleNumberProgressBar_Style); mRadius = typedArray.getDimensionPixelSize(R.styleable.CircleNumberProgressBar_cnpb_circle_radius, dp2px(30)); mBarWidth = typedArray.getDimensionPixelSize(R.styleable.CircleNumberProgressBar_cnpb_bar_width, dp2px(8)); mReachColor = typedArray.getColor(R.styleable.CircleNumberProgressBar_cnpb_reach_color, 0xFF303F9F); mUnReachColor = typedArray.getColor(R.styleable.CircleNumberProgressBar_cnpb_unreach_color, 0xFFD3D6DA); mTextSize = typedArray.getDimensionPixelSize(R.styleable.CircleNumberProgressBar_cnpb_text_size, sp2px(14)); mTextColor = typedArray.getColor(R.styleable.CircleNumberProgressBar_cnpb_text_color, 0xFF303F9F); mTextVisibility = typedArray.getInt(R.styleable.CircleNumberProgressBar_cnpb_text_visibility, VISIBLE); mUnit = typedArray.getString(R.styleable.CircleNumberProgressBar_cnpb_unit); mUnitVisibility = typedArray.getInt(R.styleable.CircleNumberProgressBar_cnpb_unit_visibility, VISIBLE); typedArray.recycle(); mPaint.setStyle(Paint.Style.STROKE); mPaint.setAntiAlias(true); mPaint.setDither(true); mPaint.setStrokeCap(Paint.Cap.ROUND); rectF = new RectF(0, 0, mRadius * 2, mRadius * 2); mBound = new Rect(); }
設定屬性之後,就到了自定義View的重點了,需要重寫onMeasure()和onDraw()方法,在onMeasure()方法中需要對View進行測量,從而確定View的測量寬高,在CircleNumberProgressBar中,onMeasure()裡面的測量程式碼如下
@Override
protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
int width = 0;
int height = 0;
switch (widthSpecMode) {
case MeasureSpec.AT_MOST :
width = Math.min(mRadius * 2 + getPaddingLeft() + getPaddingRight() + mBarWidth, widthSpecSize);
break;
case MeasureSpec.EXACTLY :
width = widthSpecSize;
break;
case MeasureSpec.UNSPECIFIED :
width = mRadius * 2 + getPaddingRight() + getPaddingLeft() + mBarWidth;
break;
}
switch (heightSpecMode) {
case MeasureSpec.AT_MOST :
height = Math.min(mRadius * 2 + getPaddingTop() + getPaddingBottom() + mBarWidth, heightSpecSize);
break;
case MeasureSpec.EXACTLY :
height = heightSpecSize;
break;
case MeasureSpec.UNSPECIFIED :
height = mRadius * 2 + getPaddingTop() + getPaddingBottom() + mBarWidth;
break;
}
int result = Math.min(width, height);
setMeasuredDimension(result, result);
}
在這裡,會先分別獲取寬高的測量模式SpecMode和對應測量模式下的規格大小SpecSize,接著會對測量模式SpecMode進行判定,並通過計算獲取真正的寬高值,要注意的是,在計算時要把padding值算進去,否則會出現誤差,在確定好寬高之後,再呼叫setMeasuredDimension方法設定寬高,這樣就能確定View的大小了
測量了View的大小後,就要對View進行繪製了,我們需要繪製圓形,圓弧和文字,圓形是用來顯示沒有達到的進度,圓弧是顯示達到的進度,文字則是在中間顯示的進度值,看看程式碼
@Override
protected synchronized void onDraw(Canvas canvas) {
super.onDraw(canvas);
String text = mUnitVisibility == VISIBLE ? getProgress() + mUnit : getProgress() + "";
float baseline = getMeasuredHeight() / 2 + mPaint.getTextSize() / 2 - mPaint.getFontMetrics().descent - getPaddingTop();
canvas.save();
canvas.translate(getPaddingLeft() + mBarWidth / 2, getPaddingTop() + mBarWidth / 2);
mPaint.setStyle(Paint.Style.STROKE);
//先繪製未達到的進度條
mPaint.setColor(mUnReachColor);
mPaint.setStrokeWidth(mBarWidth);
canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);
//再繪製已經達到的進度條
mPaint.setColor(mReachColor);
mPaint.setStrokeWidth(mBarWidth);
float angle = getProgress() * 1.0f / getMax() * 360;
canvas.drawArc(rectF, 0, angle, false, mPaint);
//繪製文字
if (mTextVisibility == VISIBLE) {
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.getTextBounds(text, 0, text.length(), mBound);
canvas.drawText(text, mRadius - mBound.width() / 2, baseline, mPaint);
}
canvas.restore();
}
在繪製時,需要先呼叫canvas.save()方法儲存畫布狀態,以免影響後續操作。在繪製圓形時,需要設定畫筆的Style為STROKE表示空心,再呼叫canvas.drawCircle方法繪製圓形,其圓心的x,y座標和半徑都是一樣的
接著繪製進度條,這裡是要繪製圓弧了,再繪製之前需要先計算圓弧的角度,這個比較簡單,根據當前值 / 最大值 * 360
的公式計算就可以了,在繪製圓弧時引數還需要一個RectF,這是用來指定繪製圓弧的外部巨星區域,這個只要設定其長高為半徑的兩倍就可以了rectF = new RectF(0, 0, mRadius * 2, mRadius * 2);
最後是繪製文字,繪製文字時要將畫筆的Style設定為FILL,接著我們需要知道文字的寬度,可以通過呼叫mPaint.getTextBounds方法先獲取到文字的邊界,再確定寬度,注意的是在canvas.drawText的方法中,第三個引數y是表示文字的基線baseline在螢幕上的位置,所以要先計算基線baseline的高,這樣才能把文字準確的繪製
繪製完成後就可進行使用啦,直接在xml檔案上進行呼叫就可以了
<com.zht.circlenumberprogressbar.widget.CircleNumberProgressBar
android:id="@+id/cnpb_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
app:cnpb_circle_radius="50dp" />
屬性值可以直接在xml檔案設定,也可以在styles檔案進行設定
<style name="CircleNumberProgressBarTheme" parent="CircleNumberProgressBar.Style">
<item name="cnpb_text_color">#FF303F9F</item>
<item name="cnpb_reach_color">#FF303F9F</item>
<item name="cnpb_unreach_color">#FFD3D6DA</item>
<item name="cnpb_text_size">16sp</item>
<item name="cnpb_text_color">#FF303F9F</item>
<item name="cnpb_text_visibility">visible</item>
<item name="cnpb_unit">%</item>
<item name="cnpb_unit_visibility">visible</item>
</style>
相關推薦
CircleNumberProgressBar:顯示數字的圓形進度條
圓形的ProgressBar是經常使用的控制元件,能夠顯示當前的進度,但有時候可能還不夠直觀,原有控制元件顯示進度時並不能準確的知道當前進度是多少,又或是遇到專案需求需要在進度條中間加上數字顯示,嗯……專案需求,所以這個時候就需要自己對原有的Progress
HTML5效果:Canvas 實現圓形進度條並顯示數字百分比
實現效果 1.首先建立html程式碼 <canvas id="canvas" width="500" he
異步下載圓形進度條顯示進度
https ati ack blog nbsp idt 進度 circle osi 圓形進度條參考鏈接即可:使用css3實現圓形進度條 需求點擊下載後遮罩層顯示下載進度: 1.圓形進度條參考以上鏈接,有點小瑕疵,可更改定位距離實現重合。 2.遮罩層: .lbOverla
Canvas實現多個圓形進度條顯示百分比,並繫結各自的click事件
Canvas實現多個圓形進度條顯示百分比,並繫結各自的click事件 目錄 Canvas實現多個圓形進度條顯示百分比並繫結各自的click事件 目錄 實現效果 製
微信小程式:靜態圓形進度條實現
效果圖: 實現: function drawCircleProgress(canvasId, backStrokeColor,strokeColor,x,y,radius,percent,text,fontSize,fontColor){ // console.l
帶動畫效果的圓形進度條顯示定時器倒計時
在實際專案開發中我們經常要使用進度條監聽下載進度,使用的大多是在UIView中的- (void)drawRect:(CGRect)rect方法中描繪圓形路徑,然後通過傳過來的進度值計算圓形路徑百分比達到監聽效果,這種監聽進度方法適合檔案下載,但是我們開發中有時會
微信小程式開發:實時圓形進度條實現
第九程式給大家帶來微信小程式開發:實時圓形進度條實現,希望大家在開發小程式過程中能夠幫助大家解決。 廢話不多說,先上一張效果圖! 實現思路 建立兩個canvas標籤,先繪製底層的淺灰色圓圈背景,再繪製上層的紅色進度條。 WXML程式碼 開始動
Android動畫篇(一):圓形進度條CircleProgressBar
前言 最近看框架和原始碼比較多,很久沒有寫動畫了,相信很多的朋友都對動畫感興趣,我也不例外,畢竟做前端還是要靠動畫特效吃飯的,並且比寫功能模組更有成就感。 今天我們就來個稍微簡單一點的CircleProgressBar熱個身。 首先需要對ValueAnim
canvas 繪制圓形進度條
設置字體大小 文字 height center body 字體 指定位置 str n) <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8">
純CSS3制作圓形進度條所遇到的問題
order 我們 消失 樣式 近日 內部 右上角 圓形進度 spa 近日在開發的頁面中,需要制作一個動態的圓形進度條,首先想到的是利用兩個矩形,寬等於直徑的一半,高等於直徑,兩個矩形利用浮動貼在一起,設置overflow:hidden屬性,作為盒子,內部有一個與其寬高相
圓形進度條
最小 element ali logs isp ber per 圖片 center 基於angularJS1/jquery和radialIndicator插件 效果圖: 1、首先引入一下文件: 2、在jsp中引入需要的文件 <script src="js
CARVARS 圓形進度條
sele int 20px 進度 arc null type eight 進度條 <!DOCTYPE html><html><head><meta charset="UTF-8"><title></title
vue慕課網音樂項目手記:30-音樂環形進度條的實現
http .org ogre bar clas VG round 慕課網 TE 環形進度條是基於svg實現的。 <template> <div class="progress-circle"> <svg :width
圓形進度條是學習
學習網站:http://www.cnblogs.com/jr1993/p/4677921.html CSS: *{
Android控制元件之圓形進度條
Android-自定義ProgressBar實現圓弧進度條 在之前的專案中用到過這個,感覺還是非常實用的,我實現的是額度的增長. 繼承於ProgressBar實現,保留了Progressbar的特性,原始碼在文尾。
白鷺egret專案資源的loading,介面的顯示與載入進度條:ProgressBar;
1.用egret建立一個空的euigame專案; 2.點選f5執行空的專案[他自帶了一個載入的txt顯示]; EE:資源太少,載入速度太快,童鞋們可能注意不到; 然後,我們在egretwing的資源路徑加如下倆資料夾; loading【放載入介面用的圖片】和Pic【放測試loa
使用自定義View繪製圓形進度條效果
首先自定義屬性 res - values - attrs(自己建立): <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyCicle">
Python中製作帶數字的進度條
簡單製作一個進度條,效果如下: 不多說,直接上程式碼: import time EACH_STEP_COST_TIME = 0.3 PROCESS_TOTAL_STEP = 40 def process_bar(current_state, total_state, bar_l
自定義View實現圓形進度條跳轉頁面
效果: //首先在values資料夾下建立一個attrs.xml: ?xml version=“1.0” encoding=“utf-8”?> //佈局: <?xml version="1.0" encoding="utf-8"?>
基於canvas的圓形進度條
建立HTML檔案,CSS檔案和JavaScript檔案,並引入jquery。 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" con