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
- 自定義圓形進度條控制元件控制元件
- [-Flutter 自定義元件-] 圓形進度條Flutter元件
- Android 自定義 View:包含多種狀態的下載用圓形進度條AndroidView
- ios自定義圓環進度條iOS
- Android 自定義圓形旋轉進度條,仿微博頭像載入效果Android
- Android自定義控制元件 帶文字提示的SeekBarAndroid控制元件
- Android花樣loading進度條(三)-配文字環形進度條Android
- 【Android】自定義樹形控制元件Android控制元件
- Flutter 波浪圓形進度條Flutter
- android自帶ProgressBar圓形進度條修改顏色的技巧方法無bug探索Android
- echarts 繪製圓形進度條帶漸變色Echarts
- 實現環形進度條效果【一】
- Android Studio通過style和layer-list實現自定義進度條Android
- android 自定義酷炫進度條動畫Android動畫
- 【Android】自定義ProgressView-進度條動畫AndroidView動畫
- VirtualView Android 實現詳解(三)—— 新增一個自定義控制元件ViewAndroid控制元件
- 實現一個協程帶進度條下載器
- 一個文字版的進度條
- 直播網站原始碼,Canvas實現圓形時間倒數計時進度條網站原始碼Canvas
- CSS3圓形進度條效果CSSS3
- 使用canvas繪製圓形進度條Canvas
- Android自定義View之圖片外形特效——輕鬆實現圓角和圓形圖片AndroidView特效
- Android 圓角、圓形 ImageView 實現AndroidView
- 【UWP】實現一個波浪進度條
- 簡單好看的Android圓形進度條對話方塊開源庫Android
- vue 自定義指令實現,滾動條百分比進度條。Vue
- Android自定義view之實現帶checkbox的SnackbarAndroidView
- android自定義view(自定義數字鍵盤)AndroidView
- carousel 輪播自定義進度條
- laravel自定義命令列印進度條Laravel命令列
- 短視訊平臺搭建,Android自定義旋轉進度條Android
- Flutter實現圓形波浪進度球【canvas+animation】FlutterCanvas
- Android自定義數字鍵盤Android
- [C#] (原創)一步一步教你自定義控制元件——04,ProgressBar(進度條)C#控制元件
- 短視訊商城系統,Android進度條,自定義進度條,顯示百分比Android
- 簡單實現帶節點的進度條
- 一對一聊天原始碼,vue實現環形進度條元件原始碼Vue元件
- Artisan 進度條 自定義輸出格式