下载进度条控件

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();
}

}

你可能感兴趣的:(下载进度条控件)