有些App在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生Button,重写onDraw来实现带进度条的按钮。

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

1.效果:

2.原理:

创建三个GradientDrawable作为按钮背景、进度条背景和进度条前景,通过计算进度条的百分比来设置宽度,然后调用invalidate()重绘。GradientDrawable设置颜色、圆角等参数,当然你也可以直接加载xml作为背景。

3.自定义参数:

在values目录建一个attrs.xml文件

 <?xml version="1.0" encoding="utf-8"?>
<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的值,然后调用invalidate()重绘,因为我这里定义了一个minProgress(默认为0),所以在计算进度条宽度的时候,当前进度和最大进度都要先减去minProgress再做除法。

if (progressWidth < mCornerRadius * 2) {
progressWidth = mCornerRadius * 2;
}
当进度条宽度小于2倍圆角半径的时候,进度条的圆角就和背景的圆角不一致,所以加上了上面这段代码。
获取宽度和高度其实用getWidth()和getHeight()也可以,只不过在设计器中没法看到效果,所以我用了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.v7.widget.AppCompatButton;
import android.util.AttributeSet; public class ProgressButton extends AppCompatButton { private float mCornerRadius = 0;
private float mProgressMargin = 0; private boolean mFinish; private int mProgress;
private int mMaxProgress = 100;
private int mMinProgress = 0; 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 2x corner radius, the radius of progress will be wrong
if (progressWidth < mCornerRadius * 2) {
progressWidth = mCornerRadius * 2;
} //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="270dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:textAllCaps="false"
android:textColor="@color/colorWhite"
android:text="@string/button_progress"
app:cornerRadius="8dp"
app:progressMargin="2dp"
app:progressColor="@color/colorGreen"
app:buttonColor="@color/colorGreen" />

Android 进度条按钮实现(ProgressButton)的更多相关文章

  1. 多种的android进度条的特效源码

    多种的android进度条的特效源码,这个源码是在源码天堂那个网站上转载过来的,我已经修改一部分了,感觉很实用的,大家可以学习一下吧,我就不上传源码了,大家可以直接到那个网站上下载吧. 源码天堂下载地 ...

  2. android进度条

    android进度条 1.达到的效果 2.布局代码 先写一个my_browser.xml文件 存放WebView <?xml version="1.0" encoding=& ...

  3. android进度条的使用

    // 导入按钮事件  btnsearch.setOnClickListener(new View.OnClickListener() {      @Override   public void on ...

  4. Android 进度条对话框ProgressDialog

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  5. Android 进度条(ProgressBar)和拖动条(Seekbar)补充“自定义组件”(总结)

    这周结束了,我也码了一周的字,感觉还是很有种脚踏实地的感觉的,有时间就可以看看自己的总结再查漏补缺,一步一个脚印,做出自己最理想的项目. 今天我们讲两点: 1.ProgressBar: 其实前面也稍微 ...

  6. Android 进度条改变图片透明度

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  7. Android 进度条

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  8. Android—进度条

    layout文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:an ...

  9. Android——进度条ProgressBar

    1.activity_progressbar.xml <?xml version="1.0" encoding="utf-8"?><Linea ...

随机推荐

  1. Java核心技术及面试指南 集合部分总的面试题归纳以及答案

    3.6.1ArrayList和LinkedList有什么差别?在哪种场景里应当用ArrayList(或LinkedList)? 大家如果学过数据结构,这个问题不难回答:前者是基于数组,数组比较擅长索引 ...

  2. HP C7000刀片服务器开关机过程

    HP C7000开关机过程   一.HP C7000关机过程 1.关闭台刀片服务器. 2.确认刀片已关机后,登录https://xxx.xxx.xxx.x/,Administrator/2PF2QT, ...

  3. 全网最详细的Centos7系统里安装Openresty(图文详解)

    不多说,直接上干货! 介绍: Nginx 采用一个 master 进程管理多个 worker 进程(master-worker)模式,基本的事件处理都在 woker 中,master 负责一些全局初始 ...

  4. Spring Boot SOAP Webservice例子

    前言 本文将学习如何利用Spring boot快速创建SOAP webservice服务: 虽然目前REST和微服务越来越流行,但是SOAP在某些情况下,仍然有它的用武之地: 在本篇 spring b ...

  5. 编写高质量代码改善java程序的151个建议——[110-117]异常及Web项目中异常处理

    原创地址:http://www.cnblogs.com/Alandre/(泥沙砖瓦浆木匠),需要转载的,保留下! 文章宗旨:Talk is cheap show me the code. 大成若缺,其 ...

  6. 2014--My Plan

    写于2014/1/10 从2014年开始我每年规划自己的life,每年10个plans. 回忆2013: 2013年,改变了很多.准确的说,那10个月,像个漫长的旅程,像个人生的转折点,应该可以这么说 ...

  7. MySql 踩坑小记

    MySql 踩坑一时爽,一直踩啊一直爽...   以下记录刚踩的三个坑,emmm... 首先是远程机子上创建表错误(踩第一个坑),于是将本地机器 MySql 版本回退至和远程一致(踩第二个坑),最后在 ...

  8. jvm详情——5、选择合适的垃圾收集算法

    回收器选择JVM给了三种选择:串行收集器.并行收集器.并发收集器,但是串行收集器只适用于小数据量的情况,所以这里的选择主要针对并行收集器和并发收集器. 默认情况下,JDK5.0以前都是使用串行收集器, ...

  9. 【原创】驱动加载之OpenSCManager

    SC_HANDLE WINAPI OpenSCManager( _In_opt_ LPCTSTR lpMachineName, _In_opt_ LPCTSTR lpDatabaseName, _In ...

  10. MySQL+MGR 单主模式和多主模式的集群环境 - 部署手册 (Centos7.5)

    MySQL Group Replication(简称MGR)是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案.MGR是MySQL官方在5.7.17版本引进的一个数据库高可用与 ...