zoukankan      html  css  js  c++  java
  • Android 进度条按钮实现(ProgressButton)

    有些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" />

     

  • 相关阅读:
    js 数据类型的转换
    js数组学习方法汇总
    跳转页面的方法总结
    今天用js做拉一个时钟
    今天用js做拉一个时钟
    js中字符的比较
    1005 继续(3n+1)猜想 (25分)
    1002 写出这个数
    日期差值
    1040 有几个PAT (25分)
  • 原文地址:https://www.cnblogs.com/cloudfloating/p/9858305.html
Copyright © 2011-2022 走看看