Android自定義控件制作顯示進(jìn)度的Button
最近看到一些應(yīng)用在下載文件的時(shí)候,并沒有額外彈出進(jìn)度條,而是很炫的使用啟動下載任務(wù)的Button直接顯示文件的下載進(jìn)度,通過改變其背景色,從左向右推進(jìn),直到填滿整個Button時(shí),意味著下載任務(wù)的完成。
除了這種效果,還看到某酷的視頻客戶端,在觀看過的視頻對應(yīng)的按鈕上,會給該按鈕添加一個描邊效果,4條邊,每條邊代表25%的進(jìn)度,由上沿開始,順時(shí)針最終到左邊沿,則代表100%的進(jìn)度,這種效果也很不錯。
自己也研究了一下,寫了個自定義的button,下面是效果,
普通的填充效果:
描邊的效果:
自定義Button的主要實(shí)現(xiàn)就是繼承Button,并重寫onDraw()方法,填充的效果實(shí)現(xiàn)起來相對簡單一點(diǎ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)前進(jìn)度來計(jì)算 rect.top += getPaddingTop(); rect.right = (rect.left - getPaddingLeft()) + (mProgress * getWidth() / 100) - getPaddingRight(); rect.bottom -= getPaddingBottom(); //繪制一個圓角的長條,這樣相對好看一點(diǎn) canvas.drawRoundRect(new RectF(rect), 8.0f, 8.0f, mPaint); }
描邊效果實(shí)現(xiàn)起來相對復(fù)雜一點(diǎn),確切說是繁瑣:
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)前進(jìn)度,確定是繪制哪條邊,其實(shí)也是繪制一個矩形,只不過這個矩形比較扁或是比較窄而已,類似一條邊 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,用于更新進(jìn)度:
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按鈕的四種點(diǎn)擊事件
- Android自定義FloatingActionButton滑動行為只隱藏不出現(xiàn)的問題小結(jié)
- Android RadioButton 圖片位置與大小實(shí)例詳解
- Android 自定義Button控件實(shí)現(xiàn)按鈕點(diǎn)擊變色
- Android中button點(diǎn)擊后字體的變色效果
- Android自定義button點(diǎn)擊效果的兩種方式
- Android手機(jī)開發(fā) 使用線性布局和相對布局實(shí)現(xiàn)Button垂直水平居中
- Android開發(fā)之創(chuàng)建可點(diǎn)擊的Button實(shí)現(xiàn)方法
- Android中EditText+Button組合導(dǎo)致輸入板無法收起的原因分析及解決辦法
- Android實(shí)現(xiàn)點(diǎn)擊Button產(chǎn)生水波紋效果
- Android編程實(shí)現(xiàn)長按Button按鈕連續(xù)響應(yīng)功能示例
相關(guān)文章
Android使用DrawerLayout實(shí)現(xiàn)側(cè)滑菜單效果
這篇文章主要為大家詳細(xì)介紹了Android使用DrawerLayout實(shí)現(xiàn)側(cè)滑菜單效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Android之日期及時(shí)間選擇對話框用法實(shí)例分析
這篇文章主要介紹了Android之日期及時(shí)間選擇對話框用法,以實(shí)例形式較為詳細(xì)的分析了Android創(chuàng)建日期及時(shí)間選擇對話框的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09將cantk runtime嵌入到現(xiàn)有的APP中的方法
今天小編就為大家分享一篇關(guān)于將cantk runtime嵌入到現(xiàn)有的APP中的方法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12Android中制作自定義dialog對話框的實(shí)例分享
這篇文章主要介紹了Android中制作自定義dialog對話框的實(shí)例分享,安卓自帶的Dialog顯然不夠用,因而我們要繼承Dialog類來制作自己的對話框,需要的朋友可以參考下2016-04-04Android基于API的Tabs3實(shí)現(xiàn)仿優(yōu)酷t(yī)abhost效果實(shí)例
這篇文章主要介紹了Android基于API的Tabs3實(shí)現(xiàn)仿優(yōu)酷t(yī)abhost效果,結(jié)合完整實(shí)例形式分析了Android實(shí)現(xiàn)優(yōu)酷界面效果的相關(guān)技巧,需要的朋友可以參考下2015-12-12Android自定義LinearLayout布局顯示不完整的解決方法
這篇文章主要給大家介紹了關(guān)于Android自定義LinearLayout但布局顯示不完整的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11