Android 自定義進(jìn)度條ColorfulProgressbar霞掺,原理簡單菩彬、效果還行

效果圖:


demo效果演示
demo效果演示

演示Demo

demo下載: https://github.com/Ccapton/Android-ColorfulProgressBar/blob/master/ColorfulProgressBarDemo_1_0_3.apk

特性

與原生Progress相比骗灶,感覺更漂亮一點(diǎn),可以顯示進(jìn)度值脱羡,背景凹凸感明顯,進(jìn)度條效果更加立體帆竹。

原理說明

額栽连,挺簡單的侨舆。不過感覺我的做法有點(diǎn)復(fù)雜了态罪,我先自定義了一個(gè)View,專門作為進(jìn)度條的顯示圖層,如下所示


將其布局在高度不超過20dp的ColorfulProgressBar父布局中,設(shè)置Y方向的偏移量耗啦,然后動(dòng)畫循環(huán)改變Y坐標(biāo)帜讲,實(shí)現(xiàn)斜條滾動(dòng)的動(dòng)畫效果,當(dāng)你調(diào)用setProgress方法時(shí)似将,則改變其在父布局的X坐標(biāo)實(shí)現(xiàn)進(jìn)度顯示的功能在验,進(jìn)度文字同樣原理添加到了父布局中腋舌。

項(xiàng)目地址

https://github.com/Ccapton/Android-ColorfulProgressBar
我的Github:
https://github.com/Ccapton

相關(guān)代碼

ColorfulProgressbar.java

 package com.capton.colorfulprogressbar;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.view.animation.TranslateAnimation;
import android.widget.TextView;
/**
 * Created by capton on 2017/8/10.
 */

public class ColorfulProgressbar extends ViewGroup {

    public static final String STYLE_NORMAL="normal";  //正常單色樣式
    public static final String STYLE_COLORFUL="colorful"; //雙色樣式
    public   String style="colorful";

    private ColorfulView colofulView;     //雙色View
    private TextView progressView;     // 第二進(jìn)度條
    private TextView maskView;         // 季度條白色漸變圖層
    private TextView percentView;       //文字顯示進(jìn)度層
    private Paint progressPaint=new Paint();  //顏色一畫筆
    private Paint progressPaint2=new Paint();  //顏色二畫筆
    private Paint backgroundPaint=new Paint();  //背景畫筆

    private  int maxHeight;  //ColorfulProgressbar高度最大值
    private  int mHeight;     //ColorfulProgressbar高度
    private  int mWidth;      //ColorfulProgressbar寬度

    private  long progress;     //進(jìn)度值
    private  long secondProgress;   //第二進(jìn)度值
    private  long maxProgress=100;  //默然最大進(jìn)度100
    private  int backgroundColor=getResources().getColor(R.color.progressBg);    //背景顏色
    private  int secondProgressColor=getResources().getColor(R.color.secondProgressColor);  //第二進(jìn)度條顏色
    private  int progressColor=getResources().getColor(R.color.colorAccent);    //進(jìn)度條顏色一
    private  int progressColor2=getResources().getColor(R.color.ltcolorAccent);  //進(jìn)度條顏色二
    private  int percentColor=Color.DKGRAY;          //進(jìn)度文字的顏色赞辩,默認(rèn)暗灰色
    private  int percentShadeColor=Color.WHITE;   //進(jìn)度文字的陰影顏色授艰,默認(rèn)白色

    private TranslateAnimation translateAnimation; //雙色進(jìn)度條的動(dòng)畫
    private boolean animationOn=true;      //動(dòng)畫開啟的標(biāo)志位
    private boolean animationCancle;         //動(dòng)畫取消的標(biāo)志位

    private boolean showPercent=true; // 是否顯示進(jìn)度文字的標(biāo)志位
    private boolean setBackgroudColor; // 是否改變背景顏色的標(biāo)志位

    public ColorfulProgressbar(Context context) {
        this(context,null);
    }
    public ColorfulProgressbar(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }
    public ColorfulProgressbar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setWillNotDraw(false);  //自定義ViewGroup淮腾,默認(rèn)不調(diào)用onDraw方法,而這里有很多步驟需要在ondraw中操作忘古,所以調(diào)用setWillNotDraw(false)
        mHeight=DisplayUtil.dip2px(context,4); //默認(rèn)進(jìn)度條高度為4dp
        getParameter(context,attrs);
    }

    /**
     * 從xml中獲取各個(gè)屬性
     * @param context
     * @param attrs
     */
    private void getParameter(Context context, AttributeSet attrs){
        if(attrs!=null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.ColorfulProgressbar);
            style = ta.getString(R.styleable.ColorfulProgressbar_style);
            if (!STYLE_NORMAL.equals(style) && !STYLE_COLORFUL.equals(style)) {
                style = STYLE_COLORFUL;  //如果沒有在xml中顯示設(shè)置style诅诱,默認(rèn)使用雙色進(jìn)度條
            }
            progress = ta.getInteger(R.styleable.ColorfulProgressbar_progress, (int)progress);
            secondProgress = ta.getInteger(R.styleable.ColorfulProgressbar_secondProgress,(int)secondProgress);
            maxProgress = ta.getInteger(R.styleable.ColorfulProgressbar_max, (int) maxProgress);
            backgroundColor = ta.getColor(R.styleable.ColorfulProgressbar_backgroundColor, backgroundColor);
            progressColor = ta.getColor(R.styleable.ColorfulProgressbar_progressColor1, progressColor);
            progressColor2 = ta.getColor(R.styleable.ColorfulProgressbar_progressColor2, progressColor2);
            ta.recycle();
            partition2= (float)this.progress/maxProgress; //進(jìn)度條百分比
            partition= (float)this.secondProgress/maxProgress; //第二進(jìn)度條百分比
        }
    }

    @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);

        widthSize=widthMode==MeasureSpec.EXACTLY?widthSize:DisplayUtil.dip2px(getContext(),200);
        heightSize=heightMode==MeasureSpec.EXACTLY?heightSize:DisplayUtil.dip2px(getContext(),4);

        /*
        * 當(dāng)你設(shè)置高度大于20dp時(shí)干旁,強(qiáng)制高度變?yōu)?0dp,太高了不美觀争群。
        * */
        maxHeight=DisplayUtil.dip2px(getContext(),20);
        if(mHeight>maxHeight) {
            mHeight = maxHeight;
        }
        /*
        * 設(shè)置高度
        * */
        if(mHeight>0){
            heightSize=mHeight;
        }

        /*
        * 在高度小于10dp時(shí)大年,強(qiáng)制不能使用文字顯示進(jìn)度翔试,因?yàn)楦叨葘?shí)在是太小了,在這個(gè)高度下字體看不清楚冲泥,放在進(jìn)度條外又不美觀壁涎,只好折中設(shè)計(jì)了。
        * */
        if(mHeight<DisplayUtil.dip2px(getContext(),10)){
            showPercent=false;
        }

        /*
        * 設(shè)置寬度
        * */
        if(mWidth>0){
            widthSize=mWidth;
        }
        setMeasuredDimension(widthSize,heightSize); //確定主視圖寬高

    }

    boolean once;
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {

         if(!once) {
             progressPaint.setColor(progressColor);
             progressPaint2.setColor(progressColor2);

             progressPaint.setAntiAlias(true);
             progressPaint2.setAntiAlias(true);

             progressView = new TextView(getContext());
             progressView.setWidth(getMeasuredWidth());
             progressView.setHeight(getMeasuredHeight());
             progressView.setBackgroundColor(secondProgressColor);

             switch (style) {
                 case STYLE_COLORFUL:
                     colofulView = new ColorfulView(getContext(), getMeasuredWidth(), progressPaint, progressPaint2);
                     break;
                 case STYLE_NORMAL:
                     colofulView = new ColorfulView(getContext(), getMeasuredWidth(), progressPaint, progressPaint);
                     break;
             }

             percentView = new TextView(getContext());
             percentView.setText((int)((float)partition2*100)+"%");
             percentView.setTextSize(DisplayUtil.px2sp(getContext(), (float) (getMeasuredHeight()*0.8)));
             percentView.setGravity(Gravity.CENTER);
             percentView.setShadowLayer(2,1,2,percentShadeColor);
              percentView.setTextColor(percentColor);
              percentView.measure(0,0);
             int textWidth = percentView.getMeasuredHeight()*2;
             int textHeight = percentView.getMeasuredHeight();

             maskView = new TextView(getContext());
             maskView.setWidth(getMeasuredWidth());
             maskView.setHeight(getMeasuredHeight() * 2 / 3);
             maskView.setBackgroundResource(R.drawable.progress_mask);

             /*
             * 依次添加第二進(jìn)度條,雙色進(jìn)度條(第一進(jìn)度條),白色漸變層流码,百分比文字顯示層等四個(gè)子View
             * */
             addView(progressView);
             addView(colofulView);
             addView(maskView);
             addView(percentView);

             getChildAt(0).layout(0, 0, getMeasuredWidth(), getMeasuredHeight()); //布局第二進(jìn)度條位置

             int ChildHeight = getMeasuredWidth();
             getChildAt(1).layout(0, -ChildHeight + getMeasuredHeight(), getMeasuredWidth(), getMeasuredWidth()); //布局雙色進(jìn)度條
             /*
             * 根據(jù)標(biāo)識(shí)位漫试,為雙色進(jìn)度條設(shè)置位移動(dòng)畫(無限向上移動(dòng)碘赖,視覺上達(dá)到斜條向右移動(dòng)的效果)
             * */
             if (animationOn) {
                 translateAnimation = new TranslateAnimation(0, 0, 0, ChildHeight - getMeasuredHeight());
                 translateAnimation.setDuration((long) (8000 * (float) getMeasuredWidth() / DisplayUtil.getScreenWidthPx(getContext())));
                 translateAnimation.setRepeatCount(-1);
                 translateAnimation.setInterpolator(new LinearInterpolator());
                 getChildAt(1).setAnimation(translateAnimation);
                 translateAnimation.start();
             }

             getChildAt(2).layout(0, 0, getMeasuredWidth(), getMeasuredHeight() * 2 / 3); //布局白色漸變層

             getChildAt(3).layout(0, 0, textWidth,textHeight); //布局百分比文字顯示層
             /*
             * 根據(jù)標(biāo)志位,確定是否顯示百分比文字顯示層审编。
             * */
             if(showPercent){
                 getChildAt(3).setVisibility(VISIBLE);
             }else {
                 getChildAt(3).setVisibility(GONE);
             }

             /*
             *  設(shè)置默認(rèn)背景圖垒酬,你當(dāng)然也可以使用純色的資源件炉。這里我用了一個(gè)黑色透明漸變的背景斟冕,呈現(xiàn)一個(gè)由陰影效果的凹槽
             * */
             setBackgroundResource(R.drawable.background);
             once=true;
         }
    }


    public void showPercentText(boolean showPercent){
        this.showPercent=showPercent;
    }

    public int getSecondProgressColor() {
        return secondProgressColor;
    }

    public void setSecondProgressColor(int secondProgressColor) {
        this.secondProgressColor = secondProgressColor;
    }
    public void setSecondProgressColorRes(int secondProgressColorRes) {
        this.secondProgressColor =  getResources().getColor(secondProgressColorRes);
    }

    public int getPercentColor() {
        return percentColor;
    }

    public void setPercentColorRes(int percentColorRes) {
        this.percentColor = getResources().getColor(percentColorRes);
    }

    public int getPercentShadeColor() {
        return percentShadeColor;
    }

    public void setPercentShadeColor(int percentShadeColor) {
        this.percentShadeColor = percentShadeColor;
    }
    public void setPercentShadeColorRes(int percentShadeColorRes) {
        this.percentShadeColor = getResources().getColor(percentShadeColorRes);
    }

    public String getStyle() {
        return style;
    }

    public void setStyle(String style) {
        this.style = style;
    }

    public int getProgressColor() {
        return progressColor;
    }

    public void setProgressColor(int progressColor) {
        this.progressColor = progressColor;
    }
    public void setProgressColorRes(int progressColorRes) {
        this.progressColor = getResources().getColor(progressColorRes);
    }

    public int getProgressColor2() {
        return progressColor2;
    }

    public void setProgressColor2(int progressColor2) {
        this.progressColor2 = progressColor2;
    }
    public void setProgressColor2Res(int progressColor2Res) {
        this.progressColor2 = getResources().getColor(progressColor2Res);
    }

    public void setAnimation(boolean animationOn){
       this.animationOn=animationOn;
   }

    public long getSecondProgress() {
        return secondProgress;
    }
    private float partition;
    public void setSecondProgress(long secondProgress) {
        this.secondProgress = secondProgress;
        partition= (float)this.secondProgress/maxProgress;
    }

    public int getBackgroundColor() {
        return backgroundColor;
    }

    public void setBackgroundColor(int backgroundColor) {
        this.backgroundColor = backgroundColor;
        setBackgroudColor=true;
    }

    public void setBackgroundColorRes(int backgroundColorRes) {
        this.backgroundColor = getResources().getColor(backgroundColorRes);
        setBackgroudColor=true;
    }

    public void setHeight(int height){
        mHeight=height;
    }
    public void setWidth(int width){
        mWidth=width;
    }

    public void setMaxProgress(long progress){
        maxProgress=progress;
    }

    public long getMaxProgress(){
       return maxProgress;
    }

    private float partition2;
    public void setProgress(long progress){
        this.progress=progress;
        partition2= (float)this.progress/maxProgress;
    }

    public long getProgress(){
        return this.progress;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
            if (getChildAt(0) != null) {
                int moveX = getMeasuredWidth() - (int) (partition * getMeasuredWidth());
                getChildAt(0).setX(-moveX);
            }
            if (getChildAt(1) != null) {
                int moveX = getMeasuredWidth() - (int) (partition2 * getMeasuredWidth());
                getChildAt(1).setX(-moveX);
            }

            if (getChildAt(2) != null) {
                int moveX = getMeasuredWidth() - (int) (partition2 * getMeasuredWidth());
                getChildAt(2).setX(-moveX);
            }
            if (getChildAt(3) != null) {

                if(getChildAt(1).getX()+getMeasuredWidth()>getChildAt(3).getMeasuredHeight()*2) {
                    getChildAt(3).setX(getChildAt(1).getX()+getMeasuredWidth()-getChildAt(3).getMeasuredHeight()*2);
                }
                percentView.setText((int) ((float) partition2 * 100) + "%");

                 /*
                 * 根據(jù)標(biāo)志位,確定是否顯示百分比文字顯示層伏伯。
                 * */
                if(showPercent){
                    getChildAt(3).setVisibility(VISIBLE);
                }else {
                    getChildAt(3).setVisibility(GONE);
                }
            }

            if (!animationOn) {
                if (translateAnimation != null) {
                    translateAnimation.cancel();
                    animationCancle = true;
                }
            } else {
                if (animationCancle) {
                    Log.w("onDraw", "translateAnimation  animationCancle");
                    translateAnimation.reset();
                    getChildAt(1).setAnimation(translateAnimation);
                    translateAnimation.startNow();
                    animationCancle = false;
                }
            }
            if(setBackgroudColor) {
                backgroundPaint.setAntiAlias(true);
                backgroundPaint.setColor(backgroundColor);
                canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), backgroundPaint);
            }
    }
}

也是挺簡單的说搅,歡迎大家來踩呀弄唧!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末霍衫,一起剝皮案震驚了整個(gè)濱河市敦跌,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麸俘,老刑警劉巖惧笛,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件患整,死亡現(xiàn)場離奇詭異,居然都是意外死亡紧憾,警方通過查閱死者的電腦和手機(jī)稻励,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門望抽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斟览,你說我怎么就攤上這事辑奈○埃” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵躁绸,是天一觀的道長净刮。 經(jīng)常有香客問我硅则,道長怎虫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任蘸际,我火速辦了婚禮捡鱼,結(jié)果婚禮上酷愧,老公的妹妹穿的比我還像新娘溶浴。我一直安慰自己,他們只是感情好闯两,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布漾狼。 她就那樣靜靜地躺著饥臂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稽煤。 梳的紋絲不亂的頭發(fā)上酵熙,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天匾二,我揣著相機(jī)與錄音庐橙,去河邊找鬼。 笑死转培,一個(gè)胖子當(dāng)著我的面吹牛浆竭,可吹牛的內(nèi)容都是我干的邦泄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼特碳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闸准,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤夷家,失蹤者是張志新(化名)和其女友劉穎敏释,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缺谴,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡湿蛔,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年阳啥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了财喳。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耳高。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡泌枪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出误证,到底是詐尸還是另有隱情,我是刑警寧澤修壕,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布愈捅,位于F島的核電站,受9級(jí)特大地震影響慈鸠,放射性物質(zhì)發(fā)生泄漏蓝谨。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望譬巫。 院中可真熱鬧稽亏,春花似錦、人聲如沸缕题。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至咸作,卻和暖如春锨阿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背记罚。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工墅诡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人桐智。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓末早,卻偏偏與公主長得像,于是被迫代替她去往敵國和親说庭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子然磷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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

  • 吊炸天!74款A(yù)PP完整源碼刊驴! [超級(jí)干貨]Android UI效果開源庫集合—你們要的支付寶RecyclerVi...
    木木00閱讀 21,025評(píng)論 0 160
  • 自己總結(jié)的Android開源項(xiàng)目及庫姿搜。 github排名https://github.com/trending,g...
    passiontim閱讀 2,538評(píng)論 1 26
  • 今日聽了《蔡康永的說話之道2》 首先要學(xué)會(huì)提問和自嘲自黑,說話有主題有結(jié)論捆憎,苦衷事后說舅柜,公事事無巨細(xì)但私下聊天多保...
    千小姐閱讀 216評(píng)論 0 1
  • 還有15天就可以回哈爾濱了,北漂生活正式結(jié)束躲惰,就要開始深漂了致份,人生太艱難了。要不停的漂泊础拨。每次不禁感嘆自己的平凡與...
    佳盈閱讀 87評(píng)論 0 0
  • 作家畢淑敏說:“書不是羽毛太伊,卻會(huì)使女人飛翔雇锡;書不是萬能的,卻會(huì)使女人千變?nèi)f化僚焦∶烫幔”不得不承認(rèn),讀書,改變了我這個(gè)農(nóng)村...
    zrongcn閱讀 680評(píng)論 4 4