Android自定義控件制作顯示進度的Button
最近看到一些應(yīng)用在下載文件的時候,并沒有額外彈出進度條,而是很炫的使用啟動下載任務(wù)的Button直接顯示文件的下載進度,通過改變其背景色,從左向右推進,直到填滿整個Button時,意味著下載任務(wù)的完成。
除了這種效果,還看到某酷的視頻客戶端,在觀看過的視頻對應(yīng)的按鈕上,會給該按鈕添加一個描邊效果,4條邊,每條邊代表25%的進度,由上沿開始,順時針最終到左邊沿,則代表100%的進度,這種效果也很不錯。
自己也研究了一下,寫了個自定義的button,下面是效果,
普通的填充效果:

描邊的效果:

自定義Button的主要實現(xiàn)就是繼承Button,并重寫onDraw()方法,填充的效果實現(xiàn)起來相對簡單一點:
if(currentType == TYPE_FILL) {
mPaint.setColor(getContext().getResources().getColor(R.color.green_yellow));
mPaint.setAntiAlias(true);
mPaint.setAlpha(128);
mPaint.setStrokeWidth(1.0f);
Rect rect = new Rect();
//先獲取Button的邊框
canvas.getClipBounds(rect);
rect.left += getPaddingLeft();
//填充條的右邊界根據(jù)當(dāng)前進度來計算
rect.top += getPaddingTop();
rect.right = (rect.left - getPaddingLeft()) + (mProgress * getWidth() / 100) - getPaddingRight();
rect.bottom -= getPaddingBottom();
//繪制一個圓角的長條,這樣相對好看一點
canvas.drawRoundRect(new RectF(rect), 8.0f, 8.0f, mPaint);
}
描邊效果實現(xiàn)起來相對復(fù)雜一點,確切說是繁瑣:
else if(currentType == TYPE_STROKE) {
//初始化畫筆
mPaint.setAntiAlias(true);
mPaint.setColor(getContext().getResources().getColor(R.color.green_yellow));
mPaint.setAlpha(255);
//獲取Button的邊框
Rect rect = new Rect();
canvas.getClipBounds(rect);
Paint paint1, paint2, paint3, paint4;
//根據(jù)當(dāng)前進度,確定是繪制哪條邊,其實也是繪制一個矩形,只不過這個矩形比較扁或是比較窄而已,類似一條邊
if(mProgress >= 0 && mProgress < 25) {
paint1 = new Paint(mPaint);
Rect temp = new Rect(rect.left + getPaddingLeft(),
rect.top + getPaddingTop(),
rect.left + mProgress * (getWidth() - getPaddingLeft() - getPaddingRight())
/ 25 - getPaddingRight(),
rect.top + getPaddingTop() + 2);
canvas.drawRect(temp, paint1);
} else if(mProgress < 50) {
paint1 = new Paint(mPaint);
Rect rect1 = new Rect(rect.left + getPaddingLeft(),
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.top + getPaddingTop() + 2);
canvas.drawRect(rect1, paint1);
paint2 = new Paint(mPaint);
Rect rect2 = new Rect(rect.right - getPaddingRight() - 2,
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.top + getPaddingTop() + (mProgress - 25) *
(getHeight() - getPaddingTop() - getPaddingBottom()) / 25);
canvas.drawRect(rect2, paint2);
} else if(mProgress < 75) {
paint1 = new Paint(mPaint);
Rect rect1 = new Rect(rect.left + getPaddingLeft(),
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.top + getPaddingTop() + 2);
canvas.drawRect(rect1, paint1);
paint2 = new Paint(mPaint);
Rect rect2 = new Rect(rect.right - getPaddingRight() - 2,
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.bottom - getPaddingBottom());
canvas.drawRect(rect2, paint2);
paint3 = new Paint(mPaint);
Rect rect3 = new Rect(
rect.right - getPaddingRight() - (mProgress - 50) *
(getWidth() - getPaddingLeft() - getPaddingRight()) / 25,
rect.bottom - getPaddingBottom() - 2,
rect.right - getPaddingRight(),
rect.bottom - getPaddingBottom());
canvas.drawRect(rect3, paint3);
} else if(mProgress <= 100) {
paint1 = new Paint(mPaint);
Rect rect1 = new Rect(
rect.left + getPaddingLeft(),
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.top + getPaddingTop() + 2);
canvas.drawRect(rect1, paint1);
paint2 = new Paint(mPaint);
Rect rect2 = new Rect(
rect.right - getPaddingRight() - 2,
rect.top + getPaddingTop(), rect.right - getPaddingRight(),
rect.bottom - getPaddingBottom());
canvas.drawRect(rect2, paint2);
paint3 = new Paint(mPaint);
Rect rect3 = new Rect(
rect.left + getCompoundPaddingLeft(),
rect.bottom - getPaddingBottom() - 2, rect.right - getPaddingRight(),
rect.bottom - getPaddingRight());
canvas.drawRect(rect3, paint3);
paint4 = new Paint(mPaint);
Rect rect4 = new Rect(
rect.left + getCompoundPaddingLeft(),
rect.bottom - getPaddingBottom() - (mProgress - 75) *
(getHeight() - getPaddingTop() - getPaddingBottom()) / 25,
rect.left + getPaddingLeft() + 2,
rect.bottom - getPaddingBottom());
canvas.drawRect(rect4, paint4);
}
}
記得最后執(zhí)行 super.onDraw(canvas);
這樣會讓填充或是描邊繪制在最底層,不會擋住Button原有的內(nèi)容。
然后添加一個API,用于更新進度:
public void updateProgress(int progress) {
if(progress >= 0 && progress <= 100) {
mProgress = progress;
invalidate();
} else if(progress < 0) {
mProgress = 0;
invalidate();
} else if(progress > 100) {
mProgress = 100;
invalidate();
}
}
Demo的代碼上傳到了github上:https://github.com/YoungLeeForeverBoy/ProgressButton
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android Button按鈕的四種點擊事件
- Android自定義FloatingActionButton滑動行為只隱藏不出現(xiàn)的問題小結(jié)
- Android RadioButton 圖片位置與大小實例詳解
- Android 自定義Button控件實現(xiàn)按鈕點擊變色
- Android中button點擊后字體的變色效果
- Android自定義button點擊效果的兩種方式
- Android手機開發(fā) 使用線性布局和相對布局實現(xiàn)Button垂直水平居中
- Android開發(fā)之創(chuàng)建可點擊的Button實現(xiàn)方法
- Android中EditText+Button組合導(dǎo)致輸入板無法收起的原因分析及解決辦法
- Android實現(xiàn)點擊Button產(chǎn)生水波紋效果
- Android編程實現(xiàn)長按Button按鈕連續(xù)響應(yīng)功能示例
相關(guān)文章
Android開發(fā)手冊RatingBar星級評分控件實例
這篇文章主要為大家介紹了Android開發(fā)手冊RatingBar星級評分控件實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06
Android 取得狀態(tài)欄、任務(wù)欄高度的小例子
Android 取得狀態(tài)欄、任務(wù)欄高度的小例子,需要的朋友可以參考一下2013-05-05
Android 字符串中某個字段可點擊和設(shè)置顏色的方法
在android開發(fā)中,我們時常會遇到對字符串中某些固定的字段實現(xiàn)可點擊和顏色的設(shè)置,現(xiàn)粘貼處我在開發(fā)中如何設(shè)置這些屬性的2017-07-07
android Gallery組件實現(xiàn)的iPhone圖片滑動效果實例
這篇文章主要介紹了android Gallery組件實現(xiàn)的iPhone圖片滑動效果實例,即相冊內(nèi)的圖片實現(xiàn)可左右滑動的效果,需要的朋友可以參考下2014-07-07
Android解析json數(shù)組對象的方法及Apply和數(shù)組的三個技巧
這篇文章主要介紹了Android解析json數(shù)組對象的方法及Apply和數(shù)組的三個技巧的相關(guān)資料,需要的朋友可以參考下2015-12-12

