DownloadProgressButton

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();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值