Android 進度條按鈕實現(ProgressButton)

来源:https://www.cnblogs.com/cloudfloating/archive/2018/10/26/9858305.html
-Advertisement-
Play Games

有些App在點擊下載按鈕的時候,可以在按鈕上顯示進度,我們可以通過繼承原生Button,重寫onDraw來實現帶進度條的按鈕。 Github:https://github.com/imcloudfloating/ProgressBar 1.效果: 2.原理: 創建三個GradientDrawable ...


有些App在點擊下載按鈕的時候,可以在按鈕上顯示進度,我們可以通過繼承原生Button,重寫onDraw來實現帶進度條的按鈕。

Github:https://github.com/imcloudfloating/ProgressBar

 

1.效果:

2.原理:

創建三個GradientDrawable作為按鈕背景、進度條背景和進度條前景,通過計算進度條的百分比來設置寬度,然後調用invalidate()重繪。GradientDrawable設置顏色、圓角等參數,當然你也可以直接載入xml作為背景。

3.自定義參數:

在values目錄建一個attrs.xml文件

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3 
 4     <attr name="progressColor" format="color" />
 5     <attr name="progressBackColor" format="color" />
 6     <attr name="progress" format="integer" />
 7     <attr name="minProgress" format="integer" />
 8     <attr name="maxProgress" format="integer" />
 9 
10     <declare-styleable name="ProgressButton">
11         <attr name="progressColor" />
12         <attr name="progressBackColor" />
13         <attr name="buttonColor" format="color" />
14         <attr name="cornerRadius" format="dimension" />
15         <attr name="progress" />
16         <attr name="minProgress" />
17         <attr name="maxProgress" />
18         <attr name="progressMargin" format="dimension" />
19     </declare-styleable>
20 
21 </resources>

3.按鈕類:

在setProgress方法中改變mProgress的值,然後調用invalidate()重繪,因為我這裡定義了一個minProgress(預設為0),所以在計算進度條寬度的時候,當前進度和最大進度都要先減去minProgress再做除法。

if (progressWidth < mCornerRadius * 2) {
progressWidth = mCornerRadius * 2;
}
當進度條寬度小於2倍圓角半徑的時候,進度條的圓角就和背景的圓角不一致,所以加上了上面這段代碼。
獲取寬度和高度其實用getWidth()和getHeight()也可以,只不過在設計器中沒法看到效果,所以我用了getMeasuredWidth()和getMeasuredHeight()。
  1 package com.cloud.customviews;
  2 
  3 import android.content.Context;
  4 import android.content.res.TypedArray;
  5 import android.graphics.Canvas;
  6 import android.graphics.drawable.GradientDrawable;
  7 import android.support.v7.widget.AppCompatButton;
  8 import android.util.AttributeSet;
  9 
 10 public class ProgressButton extends AppCompatButton {
 11 
 12     private float mCornerRadius = 0;
 13     private float mProgressMargin = 0;
 14 
 15     private boolean mFinish;
 16 
 17     private int mProgress;
 18     private int mMaxProgress = 100;
 19     private int mMinProgress = 0;
 20 
 21     private GradientDrawable mDrawableButton;
 22     private GradientDrawable mDrawableProgressBackground;
 23     private GradientDrawable mDrawableProgress;
 24 
 25     public ProgressButton(Context context, AttributeSet attrs) {
 26         super(context, attrs);
 27         initialize(context, attrs);
 28     }
 29 
 30     public ProgressButton(Context context, AttributeSet attrs, int defStyle) {
 31         super(context, attrs, defStyle);
 32         initialize(context, attrs);
 33     }
 34 
 35     private void initialize(Context context, AttributeSet attrs) {
 36         //Progress background drawable
 37         mDrawableProgressBackground = new GradientDrawable();
 38         //Progress drawable
 39         mDrawableProgress = new GradientDrawable();
 40         //Normal drawable
 41         mDrawableButton = new GradientDrawable();
 42 
 43         //Get default normal color
 44         int defaultButtonColor = getResources().getColor(R.color.colorGray, null);
 45         //Get default progress color
 46         int defaultProgressColor = getResources().getColor(R.color.colorGreen, null);
 47         //Get default progress background color
 48         int defaultBackColor = getResources().getColor(R.color.colorGray, null);
 49 
 50         TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.ProgressButton);
 51 
 52         try {
 53             mProgressMargin = attr.getDimension(R.styleable.ProgressButton_progressMargin, mProgressMargin);
 54             mCornerRadius = attr.getDimension(R.styleable.ProgressButton_cornerRadius, mCornerRadius);
 55             //Get custom normal color
 56             int buttonColor = attr.getColor(R.styleable.ProgressButton_buttonColor, defaultButtonColor);
 57             //Set normal color
 58             mDrawableButton.setColor(buttonColor);
 59             //Get custom progress background color
 60             int progressBackColor = attr.getColor(R.styleable.ProgressButton_progressBackColor, defaultBackColor);
 61             //Set progress background drawable color
 62             mDrawableProgressBackground.setColor(progressBackColor);
 63             //Get custom progress color
 64             int progressColor = attr.getColor(R.styleable.ProgressButton_progressColor, defaultProgressColor);
 65             //Set progress drawable color
 66             mDrawableProgress.setColor(progressColor);
 67 
 68             //Get default progress
 69             mProgress = attr.getInteger(R.styleable.ProgressButton_progress, mProgress);
 70             //Get minimum progress
 71             mMinProgress = attr.getInteger(R.styleable.ProgressButton_minProgress, mMinProgress);
 72             //Get maximize progress
 73             mMaxProgress = attr.getInteger(R.styleable.ProgressButton_maxProgress, mMaxProgress);
 74 
 75         } finally {
 76             attr.recycle();
 77         }
 78 
 79         //Set corner radius
 80         mDrawableButton.setCornerRadius(mCornerRadius);
 81         mDrawableProgressBackground.setCornerRadius(mCornerRadius);
 82         mDrawableProgress.setCornerRadius(mCornerRadius - mProgressMargin);
 83         setBackgroundDrawable(mDrawableButton);
 84 
 85         mFinish = false;
 86     }
 87 
 88     @Override
 89     protected void onDraw(Canvas canvas) {
 90         if (mProgress > mMinProgress && mProgress <= mMaxProgress && !mFinish) {
 91             //Calculate the width of progress
 92             float progressWidth =
 93                     (float) getMeasuredWidth() * ((float) (mProgress - mMinProgress) / mMaxProgress - mMinProgress);
 94 
 95             //If progress width less than 2x corner radius, the radius of progress will be wrong
 96             if (progressWidth < mCornerRadius * 2) {
 97                 progressWidth = mCornerRadius * 2;
 98             }
 99 
100             //Set rect of progress
101             mDrawableProgress.setBounds((int) mProgressMargin, (int) mProgressMargin,
102                     (int) (progressWidth - mProgressMargin), getMeasuredHeight() - (int) mProgressMargin);
103 
104             //Draw progress
105             mDrawableProgress.draw(canvas);
106 
107             if (mProgress == mMaxProgress) {
108                 setBackgroundDrawable(mDrawableButton);
109                 mFinish = true;
110             }
111         }
112         super.onDraw(canvas);
113     }
114 
115     /**
116      * Set current progress
117      */
118     public void setProgress(int progress) {
119         if (!mFinish) {
120             mProgress = progress;
121             setBackgroundDrawable(mDrawableProgressBackground);
122             invalidate();
123         }
124     }
125 
126     public void setMaxProgress(int maxProgress) {
127         mMaxProgress = maxProgress;
128     }
129 
130     public void setMinProgress(int minProgress) {
131         mMinProgress = minProgress;
132     }
133 
134     public void reset() {
135         mFinish = false;
136         mProgress = mMinProgress;
137     }
138 }

 使用:

 1 <com.cloud.customviews.ProgressButton
 2             android:id="@+id/button_progress_green"
 3             android:layout_width="270dp"
 4             android:layout_height="wrap_content"
 5             android:layout_marginTop="4dp"
 6             android:textAllCaps="false"
 7             android:textColor="@color/colorWhite"
 8             android:text="@string/button_progress"
 9             app:cornerRadius="8dp"
10             app:progressMargin="2dp"
11             app:progressColor="@color/colorGreen"
12             app:buttonColor="@color/colorGreen" />

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、問題 用Eclipse做項目時候報錯 java.sql.SQLException: Incorrect string value: '\xE4\xB8\x80\xE6\xAC\xA1...' for column 'excelName' at row 1。而且就只有這個表的插入有問題。 二、解決 ...
  • 從微信的誕生,到微信公眾號、微信支付,再到小程式,騰訊生態在一次又一次影響用戶行為習慣的同時,也為開發者提供了新的思路和技能發展方向。無可置疑,微信小程式開發浪潮已經來臨,也將在 2018年成為各行業流量紅利的集中爆發入口。 4月28日,騰訊雲聯合 InfoQ舉辦的雲 +社區技術沙龍,以小程式開發實 ...
  • 一.首先檢查我們的代碼: 二.註冊在主活動上的代碼需要補上: 從中我們可以看到我們註冊在XML界面上,<intent-filter>後面的代碼為<action android:name="com.example.lenovo.activitytest.ACTION_START"/>,action中間 ...
  • 任務Runnable定義了一個可以獨立運行的代碼片段,通常用於界面控制項的延遲處理,比如有時為了避免同時占用某種資源造成衝突,有時則是為了反覆間隔刷新界面從而產生動畫效果。運行一個任務也有多種形式,既可在UI線程中調用處理器對象的post或者postDelayed方法,也能另外開啟分線程來執行Runn ...
  • 微信里搜“青少兒書畫”就行了。任何人可以任意發佈自己的寶寶的作品啊。發佈作品方式有2種,一種是電腦登錄網站上用瀏覽器(chrome瀏覽器、opera瀏覽器,firefox瀏覽器等,ie的不行)發佈作品。網址是https://zsj.itdos.com/project/26171另外一種方式是用小程式 ...
  • 註釋以 <!-- 開始並以 --> 結束,例如 <!--註釋內容-->。註釋可以出現在文檔序言中,包括文檔類型定義 (DTD);文檔之後;或文本內容中。 註釋不能出現在屬性值中。 不能出現在標記中。分析器在遇到 > 時,就認為註釋已結束;然後繼續將文檔作為正常的 XML 處理。 因此,字元串 > 不 ...
  • 筆者在進行安卓開發時,發現自己的代碼語法完全沒有問題。尤其是創建intent對象的時候,語法完全是正確的,但是Android Stuidio卻顯示報錯,Intent類顯示為紅色,如圖所示: 代碼如下所示: 利用滑鼠指向Intent編譯器就會顯示: 我相信很多朋友也遇到了這個問題,至於我們該如何解決這 ...
  • 本篇針對Surface模塊進行分析,從Java層的Activity創建開始,到ViewRoot、WindowsManagerService,再到JNI層和Native層。 首先推薦一個Android源碼查看的網站:http://androidxref.com/ Surface的創建涉及三個部分: A ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...