下載進(jìn)度條控件

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 ="繼續(xù)";
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();

    // 設(shè)置默認(rèn)控件大小,默認(rèn)寬高為字體寬高二倍

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

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末捍歪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖撕彤,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件配椭,死亡現(xiàn)場離奇詭異,居然都是意外死亡合敦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門验游,熙熙樓的掌柜王于貴愁眉苦臉地迎上來充岛,“玉大人,你說我怎么就攤上這事耕蝉〈薰#” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵垒在,是天一觀的道長蒜魄。 經(jīng)常有香客問我,道長场躯,這世上最難降的妖魔是什么谈为? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮踢关,結(jié)果婚禮上伞鲫,老公的妹妹穿的比我還像新娘。我一直安慰自己签舞,他們只是感情好秕脓,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布柒瓣。 她就那樣靜靜地躺著,像睡著了一般吠架。 火紅的嫁衣襯著肌膚如雪芙贫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天诵肛,我揣著相機(jī)與錄音屹培,去河邊找鬼。 笑死怔檩,一個胖子當(dāng)著我的面吹牛褪秀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播薛训,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼媒吗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乙埃?” 一聲冷哼從身側(cè)響起闸英,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎介袜,沒想到半個月后甫何,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡遇伞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年辙喂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鸠珠。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡巍耗,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出渐排,到底是詐尸還是另有隱情炬太,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布驯耻,位于F島的核電站亲族,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏可缚。R本人自食惡果不足惜孽水,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望城看。 院中可真熱鬧,春花似錦杏慰、人聲如沸测柠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽轰胁。三九已至谒主,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赃阀,已是汗流浹背霎肯。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留榛斯,地道東北人观游。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像驮俗,于是被迫代替她去往敵國和親懂缕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 柳哲 我有幸在道光年間的一套《包氏宗譜》中王凑,發(fā)現(xiàn)了一份北宋名宦搪柑、大清官包拯手書的《包拯家訓(xùn)》,抄錄在這里索烹,與大家分...
    柳志儒閱讀 348評論 0 0
  • “斷舍離”是由日本雜物管理咨詢師山下英子創(chuàng)立的整理觀念工碾,在誕生之初就吸引了眾多的關(guān)注。從2000年起百姓,以雜物管理咨...
    乙人路閱讀 552評論 0 0
  • 見人是人話 見鬼說鬼話 人見人愛大笑話 對于自我的判斷看是不是一個情緒穩(wěn)定的人渊额,看你是看心情做事的人,還是有序地安...
    馭臨風(fēng)閱讀 792評論 1 2
  • 在哪里存在瓣戚,就在哪里綻放端圈。不要因為難過,就忘了散發(fā)芳香子库〔杖ǎ—— 渡邊和子《就在你所在的地方生根開花》 ? ??? 你...
    石川河女神閱讀 962評論 0 2
  • 七月的白天 熱浪拐走了大街上的紛擾 遺留下的冷清與孤獨 如一對失去父母的私生子 七月的夜晚 人們煩躁不安 除了驅(qū)趕...
    冷冬年閱讀 352評論 1 10