• 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" />

     

  • 相关阅读:
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 排队打水问题
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    Java实现 蓝桥杯VIP 算法提高 特殊的质数肋骨
    现在使用控件, 更喜欢继承(覆盖控件已有的函数,很奇怪的一种使用方式)
    Controls 属性与继承 TShape 类的小练习(使用TShape可以解决很多图形问题)
    QT创建窗口程序、消息循环和WinMain函数(为主线程建立了一个QEventLoop,并执行exec函数)
  • 原文地址:https://www.cnblogs.com/cloudfloating/p/9858305.html
Copyright © 2020-2023  润新知