下载进度条控件

package com.zhuoyi.common.widgets;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.zhuoyi.market.R;

/**

  • Created by wubo on 2017/11/27.
    */

public class DownLoadProgressButton extends TextView {
private static final String TAG = "DownLoadProgressButton";

private final String FREE_STATE_STR ="下载";
private final String DOWNLOADING_STATE_STR ="暂停";
private final String PAUSE_STATE_STR ="继续";
private final String DOWNLOAD_COMPLETE_STR ="安装";
private final String DOWNLOAD_COMPLETE_OPEN_STR ="打开";


public static final int DOWNLOAD_FREE_STATE =0;
public static final int DOWNLOADING_STATE=1;
public static final int DOWNLOAD_PAUSE_STATE =2;
public static final int DOWNLOAD_COMPLETE_STATE =3;
public static final int DOWNLOAD_COMPLETE_OPEN_STATE =4;
private RectF mDrawBgRectF;

private Canvas mProgressCanvas;
private Bitmap mProgressBitmap;
private int mDownLoadState;

/**
 * textSize类型是sp还是px
 */
public enum TextSizeType{
    SP,PX
}


private final int DEFAULT_TEXT_SIZE=14;

private int mMeasureWidth;
private int mMeasureHeight;


private float mTextSize;

private String mStateTextCurrent="";
private Context mContext;


private int mDefaultWidth;
private int mDefaultHeight;


private Paint mPaint=new Paint();

private Rect mTextBounds = new Rect();

private Path mPath=new Path();

private int mProgressColor;
private int mTextColor;

private float mProgressCurrent;

private float mProgressMax;


private int mCornerRadius;

private int mBorderWidth;

public DownLoadProgressButton(Context context) {
    this(context,null);
}

public DownLoadProgressButton(Context context, AttributeSet attrs) {
    this(context, attrs,0);
}
public DownLoadProgressButton(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    mContext = context;
    initParams();

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DownLoadProgressButton);
    for (int i = 0; i < a.getIndexCount(); i++) {
        switch (a.getIndex(i)) {
            case R.styleable.DownLoadProgressButton_progress_color:
                mProgressColor = a.getColor(R.styleable.DownLoadProgressButton_progress_color, Color.parseColor("#22b65d"));
                break;
            case R.styleable.DownLoadProgressButton_text_color:
                mTextColor= a.getColor(R.styleable.DownLoadProgressButton_text_color, Color.parseColor("#22b65d"));
                break;
            case R.styleable.DownLoadProgressButton_corner_radius:
                mCornerRadius=a.getDimensionPixelOffset(R.styleable.DownLoadProgressButton_corner_radius,0);
                break;
            case R.styleable.DownLoadProgressButton_text:
                mStateTextCurrent=a.getString(R.styleable.DownLoadProgressButton_text);
                break;

            case R.styleable.DownLoadProgressButton_progress:
                mProgressCurrent=a.getFloat(R.styleable.DownLoadProgressButton_progress,0);
                break;

            case R.styleable.DownLoadProgressButton_max_progress:
                mProgressMax=a.getFloat(R.styleable.DownLoadProgressButton_max_progress,100);
                break;
            }
        }
    a.recycle();
}


private void initParams() {
    mTextSize =sp2Px(DEFAULT_TEXT_SIZE);
    mBorderWidth=dp2Px(1f);
   // mStateTextCurrent= FREE_STATE_STR;
    mCornerRadius= dp2Px(10);
   // mProgressColor= Color.parseColor("#f87908");
    mTextColor=mProgressColor;
    initDefaultMeasureWidth();
    initPaint();
    mProgressMax=100;
}

private void initPaint() {
    mPaint.setAntiAlias(true);
    mPaint.setStrokeJoin(Join.ROUND);
}

private void initDefaultMeasureWidth() {
    mTextBounds.setEmpty();
    mPaint.setTextSize(mTextSize);
    mPaint.getTextBounds(mStateTextCurrent,0, mStateTextCurrent.length(),mTextBounds);

    int textWidth = mTextBounds.width();
    int textHeight = mTextBounds.height();

    // 设置默认控件大小,默认宽高为字体宽高二倍

    mDefaultWidth= (int) (textWidth*1.5f);
    mDefaultHeight=textHeight*2;
}


private float sp2Px(float sp){
   return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, mContext.getResources().getDisplayMetrics());
}

private int dp2Px(float dp){
    return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, dp, mContext.getResources().getDisplayMetrics())+0.5f);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int widthSize= MeasureSpec.getSize(widthMeasureSpec);
    int widthMode= MeasureSpec.getMode(widthMeasureSpec);
    int heightSize= MeasureSpec.getSize(heightMeasureSpec);
    int heightMode= MeasureSpec.getMode(heightMeasureSpec);

    if (widthMode == MeasureSpec.EXACTLY) {
        mMeasureWidth = widthSize;
    } else {
        if(widthSize!=0){
            mMeasureWidth = Math.min(mDefaultWidth, widthSize);
        }else{
            mMeasureWidth=mDefaultWidth;
        }
    }

    if (heightMode == MeasureSpec.EXACTLY) {
        mMeasureHeight = heightSize;
    } else {
        if(heightSize!=0){
            mMeasureHeight = Math.min(mDefaultHeight, heightSize);
        }else{
            mMeasureHeight=mDefaultHeight;
        }
    }
    mDrawBgRectF = new RectF(mBorderWidth, mBorderWidth, mMeasureWidth - mBorderWidth, mMeasureHeight - mBorderWidth);

    if(mMeasureWidth>0&&mMeasureHeight>0){
        mProgressBitmap = Bitmap.createBitmap(mMeasureWidth - mBorderWidth, mMeasureHeight - mBorderWidth, Config.ARGB_4444);
        mProgressCanvas = new Canvas(mProgressBitmap);
    }


    setMeasuredDimension(mMeasureWidth,mMeasureHeight);
}

@Override
protected void onDraw(Canvas canvas) {
    //super.onDraw(canvas);
    drawBorder(canvas);
    if(null!=mProgressBitmap){
        drawProgress(canvas);
    }
    drawText(canvas);
    drawProgressShadeText(canvas);
}

private void drawProgressShadeText(Canvas canvas) {
    mPaint.setColor(Color.WHITE);
    FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
    int tWidth =mTextBounds.width();
    float xCoordinate = (mMeasureWidth - tWidth) / 2;
    float baseline  = (mMeasureHeight -fontMetricsInt.bottom+fontMetricsInt.top) / 2-fontMetricsInt.top;
    float progressWidth = (mProgressCurrent / mProgressMax) *mMeasureWidth;
    if(progressWidth > xCoordinate){
        canvas.save(Canvas.CLIP_SAVE_FLAG);
        float right = Math.min(progressWidth, xCoordinate + tWidth * 1.1f);
        canvas.clipRect(xCoordinate, 0, right, mMeasureHeight);
        canvas.drawText(mStateTextCurrent, xCoordinate, baseline, mPaint);
        canvas.restore();
    }
}

private void drawText(Canvas canvas) {
    mTextBounds.setEmpty();
    mPaint.setColor(mTextColor);
    mPaint.getTextBounds(mStateTextCurrent, 0, mStateTextCurrent.length(), mTextBounds);
    FontMetricsInt fontMetricsInt = mPaint.getFontMetricsInt();
    int tWidth =mTextBounds.width();
    float xCoordinate = (mMeasureWidth - tWidth) / 2;
    float baseline  = (mMeasureHeight -fontMetricsInt.bottom+fontMetricsInt.top) / 2-fontMetricsInt.top;
    canvas.drawText(mStateTextCurrent, xCoordinate, baseline, mPaint);
}

private void drawProgress(Canvas canvas) {
    mPaint.setStyle(Paint.Style.FILL);
    //mPaint.setStrokeWidth(0);
    mPaint.setColor(mProgressColor);

    mProgressCanvas.save(Canvas.CLIP_SAVE_FLAG);
    float right = (mProgressCurrent / mProgressMax) * mMeasureWidth;
    mProgressCanvas.clipRect(0, 0, right, mMeasureHeight);
    mProgressCanvas.drawColor(mProgressColor );
    mProgressCanvas.restore();
    mPaint.setShader(new BitmapShader(mProgressBitmap, TileMode.CLAMP, TileMode.CLAMP));
    canvas.drawRoundRect(mDrawBgRectF,mCornerRadius, mCornerRadius, mPaint);
    mPaint.setShader(null);

}

private void drawBorder(Canvas canvas) {
    mPaint.setStyle(Style.STROKE);
    mPaint.setColor(mProgressColor);
    mPaint.setStrokeWidth(dp2Px(0.5f));
   // mPath.moveTo(mCornerRadius,0);

/* mPath.moveTo(mCornerRadius,0);
mPath.lineTo(mMeasureWidth-mCornerRadius,0);
mPath.moveTo(mMeasureWidth-mCornerRadius,0);
mPath.quadTo(mMeasureWidth,0,mMeasureWidth,mCornerRadius);
mPath.moveTo(mMeasureWidth,mCornerRadius);
mPath.lineTo(mMeasureWidth,mMeasureHeight-mCornerRadius);
mPath.moveTo(mMeasureWidth,mMeasureHeight-mCornerRadius);
mPath.quadTo(mMeasureWidth,mMeasureHeight,mMeasureWidth-mCornerRadius,mMeasureHeight);
mPath.moveTo(mMeasureWidth-mCornerRadius,mMeasureHeight);
mPath.lineTo(mCornerRadius,mMeasureHeight);
mPath.moveTo(mCornerRadius,mMeasureHeight);
mPath.quadTo(0,mMeasureHeight,0,mMeasureHeight-mCornerRadius);
mPath.moveTo(0,mMeasureHeight-mCornerRadius);
mPath.lineTo(0,mCornerRadius);
mPath.moveTo(0,mCornerRadius);
mPath.quadTo(0,0,mCornerRadius,0);
*/
canvas.drawRoundRect(mDrawBgRectF,mCornerRadius,mCornerRadius, mPaint);
}

public void setProgress(float progress){
    if(progress>=mProgressMax){
        mProgressCurrent=mProgressMax;
    }else{
        mProgressCurrent=progress;
    }
    invalidate();
}

public void setMaxProgress(float progressMax){
    mProgressMax=progressMax;
}


public void  setState(int downLoadState){
    mDownLoadState = downLoadState;
    Log.e(TAG,"downLoadState: "+downLoadState);
    switch (downLoadState){
        case DOWNLOAD_FREE_STATE:
            mStateTextCurrent=FREE_STATE_STR;
            break;
        case DOWNLOADING_STATE:
            mStateTextCurrent=DOWNLOADING_STATE_STR;
            break;
        case DOWNLOAD_PAUSE_STATE:
            mStateTextCurrent=PAUSE_STATE_STR;
            break;
        case DOWNLOAD_COMPLETE_OPEN_STATE:
            mStateTextCurrent=DOWNLOAD_COMPLETE_OPEN_STR;
            break;
        case DOWNLOAD_COMPLETE_STATE:
            mStateTextCurrent=DOWNLOAD_COMPLETE_STR;
            break;
    }
    invalidate();
}


public void setTextSize(int textSize,TextSizeType sizeType){
   if(sizeType== TextSizeType.SP){
       mTextSize =sp2Px(textSize);
   }else if(sizeType== TextSizeType.PX){
       mTextSize=textSize;
   }
    initDefaultMeasureWidth();
    requestLayout();
}


public int getDownLoadState(){
    return mDownLoadState;
}

public void setProgressColor(int color){
    mProgressColor=color;
    invalidate();
}


/**
 *  set text
 * */

public void setButtonText(String text){
    mStateTextCurrent=text;
    initDefaultMeasureWidth();
    requestLayout();
}

public void setCornerRadius(int radius){
    mCornerRadius=radius;
    invalidate();
}

public void setTextColor(int textColor){
    mTextColor=textColor;
    invalidate();
}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容

  • 柳哲 我有幸在道光年间的一套《包氏宗谱》中,发现了一份北宋名宦、大清官包拯手书的《包拯家训》,抄录在这里,与大家分...
    柳志儒阅读 343评论 0 0
  • “断舍离”是由日本杂物管理咨询师山下英子创立的整理观念,在诞生之初就吸引了众多的关注。从2000年起,以杂物管理咨...
    乙人路阅读 539评论 0 0
  • 见人是人话 见鬼说鬼话 人见人爱大笑话 对于自我的判断看是不是一个情绪稳定的人,看你是看心情做事的人,还是有序地安...
    驭临风阅读 756评论 1 2
  • 在哪里存在,就在哪里绽放。不要因为难过,就忘了散发芳香。—— 渡边和子《就在你所在的地方生根开花》 ​ ​​​ 你...
    石川河女神阅读 953评论 0 2
  • 七月的白天 热浪拐走了大街上的纷扰 遗留下的冷清与孤独 如一对失去父母的私生子 七月的夜晚 人们烦躁不安 除了驱赶...
    冷冬年阅读 343评论 1 10