Android 進(jìn)度條按鈕ProgressButton的實(shí)現(xiàn)代碼
有些App在點(diǎn)擊下載按鈕的時(shí)候,可以在按鈕上顯示進(jìn)度,我們可以通過繼承原生Button,重寫onDraw來實(shí)現(xiàn)帶進(jìn)度條的按鈕。
Github:https://github.com/imcloudfloating/ProgressBar
1.效果:

2.原理:
創(chuàng)建三個(gè)GradientDrawable作為按鈕背景、進(jìn)度條背景和進(jìn)度條前景,通過計(jì)算進(jìn)度條的百分比來設(shè)置寬度,然后調(diào)用invalidate()重繪。GradientDrawable設(shè)置顏色、圓角等參數(shù),當(dāng)然你也可以直接加載xml作為背景。
3.自定義參數(shù):
在values目錄建一個(gè)attrs.xml文件
<?xml version="." encoding="utf-"?> <resources> <attr name="progressColor" format="color" /> <attr name="progressBackColor" format="color" /> <attr name="progress" format="integer" /> <attr name="minProgress" format="integer" /> <attr name="maxProgress" format="integer" /> <declare-styleable name="ProgressButton"> <attr name="progressColor" /> <attr name="progressBackColor" /> <attr name="buttonColor" format="color" /> <attr name="cornerRadius" format="dimension" /> <attr name="progress" /> <attr name="minProgress" /> <attr name="maxProgress" /> <attr name="progressMargin" format="dimension" /> </declare-styleable> </resources>
3.按鈕類:
在setProgress方法中改變mProgress的值,然后調(diào)用invalidate()重繪,因?yàn)槲疫@里定義了一個(gè)minProgress(默認(rèn)為0),所以在計(jì)算進(jìn)度條寬度的時(shí)候,當(dāng)前進(jìn)度和最大進(jìn)度都要先減去minProgress再做除法。
if (progressWidth < mCornerRadius * 2) {
progressWidth = mCornerRadius * 2;
}
當(dāng)進(jìn)度條寬度小于2倍圓角半徑的時(shí)候,進(jìn)度條的圓角就和背景的圓角不一致,所以加上了上面這段代碼。
獲取寬度和高度其實(shí)用getWidth()和getHeight()也可以,只不過在設(shè)計(jì)器中沒法看到效果,所以我用了getMeasuredWidth()和getMeasuredHeight()。
package com.cloud.customviews;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.drawable.GradientDrawable;
import android.support.v.widget.AppCompatButton;
import android.util.AttributeSet;
public class ProgressButton extends AppCompatButton {
private float mCornerRadius = ;
private float mProgressMargin = ;
private boolean mFinish;
private int mProgress;
private int mMaxProgress = ;
private int mMinProgress = ;
private GradientDrawable mDrawableButton;
private GradientDrawable mDrawableProgressBackground;
private GradientDrawable mDrawableProgress;
public ProgressButton(Context context, AttributeSet attrs) {
super(context, attrs);
initialize(context, attrs);
}
public ProgressButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize(context, attrs);
}
private void initialize(Context context, AttributeSet attrs) {
//Progress background drawable
mDrawableProgressBackground = new GradientDrawable();
//Progress drawable
mDrawableProgress = new GradientDrawable();
//Normal drawable
mDrawableButton = new GradientDrawable();
//Get default normal color
int defaultButtonColor = getResources().getColor(R.color.colorGray, null);
//Get default progress color
int defaultProgressColor = getResources().getColor(R.color.colorGreen, null);
//Get default progress background color
int defaultBackColor = getResources().getColor(R.color.colorGray, null);
TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.ProgressButton);
try {
mProgressMargin = attr.getDimension(R.styleable.ProgressButton_progressMargin, mProgressMargin);
mCornerRadius = attr.getDimension(R.styleable.ProgressButton_cornerRadius, mCornerRadius);
//Get custom normal color
int buttonColor = attr.getColor(R.styleable.ProgressButton_buttonColor, defaultButtonColor);
//Set normal color
mDrawableButton.setColor(buttonColor);
//Get custom progress background color
int progressBackColor = attr.getColor(R.styleable.ProgressButton_progressBackColor, defaultBackColor);
//Set progress background drawable color
mDrawableProgressBackground.setColor(progressBackColor);
//Get custom progress color
int progressColor = attr.getColor(R.styleable.ProgressButton_progressColor, defaultProgressColor);
//Set progress drawable color
mDrawableProgress.setColor(progressColor);
//Get default progress
mProgress = attr.getInteger(R.styleable.ProgressButton_progress, mProgress);
//Get minimum progress
mMinProgress = attr.getInteger(R.styleable.ProgressButton_minProgress, mMinProgress);
//Get maximize progress
mMaxProgress = attr.getInteger(R.styleable.ProgressButton_maxProgress, mMaxProgress);
} finally {
attr.recycle();
}
//Set corner radius
mDrawableButton.setCornerRadius(mCornerRadius);
mDrawableProgressBackground.setCornerRadius(mCornerRadius);
mDrawableProgress.setCornerRadius(mCornerRadius - mProgressMargin);
setBackgroundDrawable(mDrawableButton);
mFinish = false;
}
@Override
protected void onDraw(Canvas canvas) {
if (mProgress > mMinProgress && mProgress <= mMaxProgress && !mFinish) {
//Calculate the width of progress
float progressWidth =
(float) getMeasuredWidth() * ((float) (mProgress - mMinProgress) / mMaxProgress - mMinProgress);
//If progress width less than x corner radius, the radius of progress will be wrong
if (progressWidth < mCornerRadius * ) {
progressWidth = mCornerRadius * ;
}
//Set rect of progress
mDrawableProgress.setBounds((int) mProgressMargin, (int) mProgressMargin,
(int) (progressWidth - mProgressMargin), getMeasuredHeight() - (int) mProgressMargin);
//Draw progress
mDrawableProgress.draw(canvas);
if (mProgress == mMaxProgress) {
setBackgroundDrawable(mDrawableButton);
mFinish = true;
}
}
super.onDraw(canvas);
}
/**
* Set current progress
*/
public void setProgress(int progress) {
if (!mFinish) {
mProgress = progress;
setBackgroundDrawable(mDrawableProgressBackground);
invalidate();
}
}
public void setMaxProgress(int maxProgress) {
mMaxProgress = maxProgress;
}
public void setMinProgress(int minProgress) {
mMinProgress = minProgress;
}
public void reset() {
mFinish = false;
mProgress = mMinProgress;
}
}
使用:
<com.cloud.customviews.ProgressButton
android:id="@+id/button_progress_green"
android:layout_width="dp"
android:layout_height="wrap_content"
android:layout_marginTop="dp"
android:textAllCaps="false"
android:textColor="@color/colorWhite"
android:text="@string/button_progress"
app:cornerRadius="dp"
app:progressMargin="dp"
app:progressColor="@color/colorGreen"
app:buttonColor="@color/colorGreen" />
總結(jié)
以上所述是小編給大家介紹的Android 進(jìn)度條按鈕ProgressButton的實(shí)現(xiàn)代碼,希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言小編會(huì)及時(shí)回復(fù)大家的!
相關(guān)文章
Google 開發(fā)Android MVP架構(gòu)Demo深入解析
這篇文章主要為大家介紹了Google 開發(fā)Android MVP架構(gòu)Demo深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
Android開發(fā)之滑動(dòng)數(shù)值選擇器NumberPicker用法示例
這篇文章主要介紹了Android開發(fā)之滑動(dòng)數(shù)值選擇器NumberPicker用法,結(jié)合實(shí)例形式分析了Android滑動(dòng)數(shù)值選擇器NumberPicker的功能、相關(guān)函數(shù)、事件監(jiān)聽、界面布局等操作技巧,需要的朋友可以參考下2019-03-03
實(shí)現(xiàn)Android 滑動(dòng)退出Activity的功能
這篇文章主要介紹了實(shí)現(xiàn)Android 滑動(dòng)退出Activity的功能的相關(guān)資料,這里提供實(shí)例來說明滑動(dòng)退出應(yīng)用程序的實(shí)現(xiàn)代碼,需要的朋友可以參考下2017-08-08
Android自定義View實(shí)現(xiàn)仿GitHub的提交活躍表格
這篇文章主要介紹了Android自定義View實(shí)現(xiàn)仿GitHub的提交活躍表格,非常不錯(cuò),具有參考借鑒價(jià)值,需要的的朋友參考下吧2017-01-01
Android仿微信發(fā)送語(yǔ)音消息的功能及示例代碼
這篇文章主要介紹了Android仿微信發(fā)送語(yǔ)音消息的功能及示例代碼,需要的朋友參考下吧2017-08-08
Android開發(fā)之開發(fā)者頭條APP(三)實(shí)現(xiàn)首頁(yè)
這篇文章主要介紹了Android開發(fā)之開發(fā)者頭條APP(三)實(shí)現(xiàn)首頁(yè)的相關(guān)資料,需要的朋友可以參考下2016-04-04
Android ListView物流獲取追蹤功能實(shí)現(xiàn)
這篇文章主要介紹了Android ListView物流獲取追蹤功能實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2016-03-03

