Android自定義控制元件實現一個帶文字與數字的圓形進度條
實現的效果圖如下所示:
第一步:繪製下方有缺口的空心圓,稱為外圍大弧吧
anvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4);第二步:計算繪製圓弧進度條時的起始角度,設定為外圍大弧的左端點為進度值得起點,掃過的角度所佔外圍大弧的百分比就是進度值
第三步:繪製數字、文字、百分號
第四步:使用Handler Runnable 和DecelerateInterpolator是進度條和數字動起來
測試程式碼:
final CustomCircleBar circle=(CustomCircleBar)findViewById(R.id.win_home); circle.setPercent(10); circle.setCustomText("呵呵"); circle.setProgessColor(getResources().getColor(R.color.blue)); final Random random=new Random(); circle.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v){ circle.setPercent(random.nextInt(100)); } });完成程式碼如下:
public class CustomCircleBar extends View {
private Context context;
/*進度值*/
private int percent;
/*顏色值*/
private int mProgessColor;
/*下邊的文字名稱*/
private String mCustomText;
/*外圈圓環的畫筆*/
private Paint paintBar = new Paint();
/*下邊文字的畫筆*/
private Paint paintText = new Paint();
/*動態獲取屬性值*/
private TypedValue typedValue;
/*先加速後減速*/
DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
/*動畫持續時間*/
private int duration = 10;
private int curTime = 0;
public CustomCircleBar(Context context) {
super(context);
this.context=context;
init();
}
public CustomCircleBar(Context context, AttributeSet attrs) {
super(context, attrs);
this.context=context;
init();
}
public CustomCircleBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context=context;
init();
}
public void setPercent(int percent) {
this.percent = percent;
/*isShown():Returns the visibility of this view and all of its ancestors*/
if (isShown()) {
/*設定進度後重新開始一次動畫*/
curTime=0;
this.invalidate();
}
}
public void setProgessColor(int mProgessColor) {
this.mProgessColor = mProgessColor;
if (isShown()) {
this.invalidate();
}
}
public void setCustomText(String mCustomText) {
this.mCustomText = mCustomText;
}
private Handler mHandler = new Handler();
private Runnable mAnimation = new Runnable() {
@Override
public void run() {
if (curTime < duration) {
curTime++;
/*導致重繪,呼叫onDraw,onDraw最後呼叫
* mHandler.postDelayed(mAnimation, 20);更新進度條,介面重繪
* 每次20毫秒,繪製10次,因此動畫時間200毫秒*/
CustomCircleBar.this.invalidate();
}
}
};
private void init() {
/*資料初始化,沒有設定屬性時候的預設值*/
percent = 0;
mProgessColor=Color.rgb(95,112,72);
mCustomText="Home";
typedValue=new TypedValue();
context.getTheme().resolveAttribute(R.attr.maintextclor,typedValue,true);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float mWidth = getWidth();
float mHeight = getHeight();
/*下邊是進度條畫筆的設定*/
/** Restores the paint to its default settings. */
paintBar.reset();
/*圓環寬度4個畫素*/
paintBar.setStrokeWidth(4);
/*空心圓環而非填充的額扇形*/
paintBar.setStyle(Paint.Style.STROKE);
paintBar.setAntiAlias(true);
paintBar.setColor(mProgessColor);
/*調整下不透明度,使邊框弧和進度條區分開*/
paintBar.setAlpha(80);
/*接下來是文字畫筆的設定*/
paintText.setTextSize(20);
paintText.setColor(getResources().getColor(typedValue.resourceId));
paintText.setStyle(Paint.Style.STROKE);
paintText.setAntiAlias(true);
/*從中間開始繪製文字*/
paintText.setTextAlign(Paint.Align.CENTER);
/*測量文字大小*/
Paint.FontMetrics fontMetrics = paintText.getFontMetrics();
/*計算文字高度*/
float textHeight = fontMetrics.bottom - fontMetrics.top;
/*計算圓的半徑*/
float radius = Math.min(mWidth, mHeight) / 2 - 10;
/* ❑ save:用來儲存Canvas的狀態。save之後,可以呼叫Canvas的平移、放縮、旋轉、錯切、裁剪等操作。
❑ restore:用來恢復Canvas之前儲存的狀態。防止save後對Canvas執行的操作對後續的繪製有影響。*/
/*儲存畫布,繪製進度條*/
canvas.save();
/*clipRect:該方法用於裁剪畫布,也就是設定畫布的顯示區域
呼叫clipRect()方法後,只會顯示被裁剪的區域,之外的區域將不會顯示 */
canvas.clipRect(0, 0, mWidth, mHeight / 2 + radius - textHeight * 3 / 4);
/*因為clipRect的原因,外邊的圓環下邊留個缺口繪製文字*/
canvas.drawCircle(mWidth / 2, mHeight / 2, radius, paintBar);
/*三角函式計算,下方缺口扇形的角度的一半*/
float theta_offset = (float) Math.acos((radius - textHeight / 2) / radius);
/*大弧圍成的扇形的角度*/
float theta_full = 360 - 2 * theta_offset;
/*進度值圍成的弧對應的角度*/
float thetaProcess = mDecelerateInterpolator.getInterpolation(1.0f * curTime / duration) * percent * theta_full / 100;
/*設定進度值顏色完全不透明*/
paintBar.setAlpha(255);
paintBar.setColor(mProgessColor);
/*注意弧形的起始角度,下邊因顯示文字導致圓環斷開成一條弧,弧有左右兩個端點,從左端點開始畫弧*/
canvas.drawArc(new RectF(mWidth / 2 - radius, mHeight / 2 - radius, mWidth / 2 + radius, mHeight / 2 + radius), theta_offset+90, thetaProcess, false, paintBar);
/*恢復畫布*/
canvas.restore();
/*開始繪製文字*/
paintText.setTextSize(20);
fontMetrics = paintText.getFontMetrics();
float textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
canvas.drawText(mCustomText, mWidth / 2, mHeight / 2 + radius - textHeight / 2 + textBaseLineOffset, paintText);
/*繪製百分號*/
paintText.setTextSize(mHeight * 1 / 8);
fontMetrics = paintText.getFontMetrics();
textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
canvas.drawText("%", mWidth / 2, mHeight / 2 + radius / 3 + textBaseLineOffset, paintText);
/*繪製百分比*/
paintText.setTextSize(mHeight * 3 / 8);
canvas.drawText("" + (int)(percent*mDecelerateInterpolator.getInterpolation(1.0f * curTime / duration)), mWidth / 2, mHeight / 2, paintText);
/*20毫秒後執行動畫*/
mHandler.postDelayed(mAnimation, 20);
}
}
相關文章
- Android開發自定義控制元件實現一個圓形進度條【帶數值和動畫】Android控制元件動畫
- Android自定義控制元件系列之圓形進度條的實現Android控制元件
- Android自定義圓形進度條實現程式碼Android
- Android自定義圓形進度條Android
- 自定義圓形進度條
- Android自定義View——從零開始實現圓形進度條AndroidView
- Android自定義圓形進度條原始碼解析Android原始碼
- Android進階 自定義View(三)圓形刻度進度條AndroidView
- Android 自定義控制元件一 帶圓形進度的按鈕 ControlButton2Android控制元件
- Android閃屏頁圓形倒數計時進度條實現Android
- Android Paint應用之自定義View實現進度條控制元件AndroidAIView控制元件
- [-Flutter 自定義元件-] 圓形進度條Flutter元件
- 3個自定義view佈局:矩形TextView,圓形進度條,圓環viewTextView
- iOS專案開發實戰——自定義圓形進度提示控制元件iOS控制元件
- Android 自定義 View:包含多種狀態的下載用圓形進度條AndroidView
- Android 自定義圓形旋轉進度條,仿微博頭像載入效果Android
- Android圓形圖片--自定義控制元件Android控制元件
- Android自定義控制元件之實現一個球賽比分條Android控制元件
- Flutter 波浪圓形進度條Flutter
- SVG畫圓形進度條SVG
- Android自定義控制元件 帶文字提示的SeekBarAndroid控制元件
- Android自定義設定圓形圖片控制元件Android控制元件
- 實現環形進度條效果【一】
- Android開發自定義控制元件實現一個球賽勝負數統計條Android控制元件
- 圓形進度條+二維碼掃描+自定義組合控制元件標題欄+自定義矩形view+介面回撥方法控制元件View
- 自定義進度條
- canvas的簡單圓形進度條Canvas
- Android 自定義圓形頭像Android
- Android自定義圓形頭像Android
- android自帶ProgressBar圓形進度條修改顏色的技巧方法無bug探索Android
- 【Android】自定義ProgressView-進度條動畫AndroidView動畫
- android 自定義酷炫進度條動畫Android動畫
- Android花樣loading進度條(三)-配文字環形進度條Android
- Android 編寫一個帶進度條的WebviewAndroidWebView
- 自定義view - 進度條View
- 自定義進度條列表
- iOS 自定義進度條iOS
- CSS3圓形進度條效果CSSS3