一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Android实现带数字的圆形进度条(自定义进度条)

时间:2017-03-16 编辑:简简单单 来源:一聚教程网

开发

设计搞了一个带圆形进度的进度条,在GitHub上逛了一圈,发现没有,自己撸吧。

先看界面效果:

自定义进度条

主要思路是写一个继承ProgressBar的自定义View,不废话,直接上代码:

 代码如下复制代码

packagecom.fun.progressbarwithnumber;

importandroid.content.Context;

importandroid.content.res.TypedArray;

importandroid.graphics.Canvas;

importandroid.graphics.Paint;

importandroid.graphics.RectF;

importandroid.util.AttributeSet;

importandroid.util.TypedValue;

importandroid.widget.ProgressBar;

publicclassHorizontalProgressBarWithNumberextendsProgressBar {

  privatestaticfinalintDEFAULT_TEXT_SIZE =10;

  privatestaticfinalintDEFAULT_TEXT_COLOR =0XFFFC00D1;

  privatestaticfinalintDEFAULT_COLOR_UNREACHED_COLOR =0xFFd3d6da;

  privatestaticfinalintDEFAULT_HEIGHT_REACHED_PROGRESS_BAR =2;

  privatestaticfinalintDEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR =2;

  privatestaticfinalintDEFAULT_CIRCLE_COLOR =0XFF3F51B5;

  protectedPaint mPaint =newPaint();

  // 字体颜色

  protectedintmTextColor = DEFAULT_TEXT_COLOR;

  // 字体大小

  protectedintmTextSize = sp2px(DEFAULT_TEXT_SIZE);

  // 覆盖进度高度

  protectedintmReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_REACHED_PROGRESS_BAR);

  // 覆盖进度颜色

  protectedintmReachedBarColor = DEFAULT_TEXT_COLOR;

  // 未覆盖进度高度

  protectedintmUnReachedProgressBarHeight = dp2px(DEFAULT_HEIGHT_UNREACHED_PROGRESS_BAR);

  // 未覆盖进度颜色

  protectedintmUnReachedBarColor = DEFAULT_COLOR_UNREACHED_COLOR;

  // 圆的颜色

  protectedintmCircleColor = DEFAULT_CIRCLE_COLOR;

  protectedintmRealWidth;

  protectedbooleanmIfDrawText =true;

  protectedbooleanmIfDrawCircle =true;

  protectedstaticfinalintVISIBLE =0;

  publicHorizontalProgressBarWithNumber(Context context, AttributeSet attrs) {

    this(context, attrs,0);

  }

  publicHorizontalProgressBarWithNumber(Context context, AttributeSet attrs,intdefStyle) {

    super(context, attrs, defStyle);

    obtainStyledAttributes(attrs);

    mPaint.setTextSize(mTextSize);

    mPaint.setColor(mTextColor);

    mPaint.setAntiAlias(true);

  }

  privatevoidobtainStyledAttributes(AttributeSet attrs) {

    // 获取自定义属性

    finalTypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.HorizontalProgressBarWithNumber);

    mTextColor = attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_text_color, DEFAULT_TEXT_COLOR);

    mTextSize = (int) attributes.getDimension(R.styleable.HorizontalProgressBarWithNumber_progress_text_size, mTextSize);

    mCircleColor = attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_circle_color, DEFAULT_CIRCLE_COLOR);

    mReachedBarColor = attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_reached_color, mTextColor);

    mUnReachedBarColor = attributes.getColor(R.styleable.HorizontalProgressBarWithNumber_progress_unreached_color, DEFAULT_COLOR_UNREACHED_COLOR);

    mReachedProgressBarHeight = (int) attributes.getDimension(R.styleable.HorizontalProgressBarWithNumber_progress_reached_bar_height, mReachedProgressBarHeight);

    mUnReachedProgressBarHeight = (int) attributes.getDimension(R.styleable.HorizontalProgressBarWithNumber_progress_unreached_bar_height, mUnReachedProgressBarHeight);

    inttextVisible = attributes.getInt(R.styleable.HorizontalProgressBarWithNumber_progress_text_visibility, VISIBLE);

    if(textVisible != VISIBLE) {

      mIfDrawText =false;

    }

    attributes.recycle();

    intleft = (int) (mReachedProgressBarHeight *0.8), right = (int) (mReachedProgressBarHeight *0.8);

    inttop = (int) (mReachedProgressBarHeight *0.3+ dp2px(1)), bottom = (int) (mReachedProgressBarHeight *0.3+ dp2px(1));

    setPadding(left, top, right, bottom);

  }

  @Override

  protectedsynchronizedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec) {

    intwidth = MeasureSpec.getSize(widthMeasureSpec);

    intheight = measureHeight(heightMeasureSpec);

    setMeasuredDimension(width, height);

    mRealWidth = getMeasuredWidth() - getPaddingRight() - getPaddingLeft();

  }

  privateintmeasureHeight(intmeasureSpec) {

    intresult;

    intspecMode = MeasureSpec.getMode(measureSpec);

    intspecSize = MeasureSpec.getSize(measureSpec);

    if(specMode == MeasureSpec.EXACTLY) {

      result = specSize;

    }else{

      floattextHeight = (mPaint.descent() - mPaint.ascent());

      result = (int) (getPaddingTop() + getPaddingBottom() + Math.max(

          Math.max(mReachedProgressBarHeight, mUnReachedProgressBarHeight), Math.abs(textHeight)));

      if(specMode == MeasureSpec.AT_MOST) {

        result = Math.min(result, specSize);

      }

    }

    returnresult;

  }

  @Override

  protectedsynchronizedvoidonDraw(Canvas canvas) {

    canvas.save();

    canvas.translate(getPaddingLeft(), getHeight() /2);

    booleannoNeedBg =false;

    floatradio = getProgress() *1.0f / getMax();

    floatprogressPosX = (int) (mRealWidth * radio);

    String text = getProgress() +"%";

    floattextWidth = mPaint.measureText(text);

    floattextHeight = (mPaint.descent() + mPaint.ascent()) /2;

    floatradius = (mReachedProgressBarHeight + getPaddingBottom() + getPaddingTop()) /2;

    // 覆盖的进度

    floatendX = progressPosX;

    if(endX > -1) {

      mPaint.setColor(mReachedBarColor);

      RectF rectF =newRectF(0,0- getPaddingTop() - getPaddingBottom(),

          endX, mReachedProgressBarHeight - getPaddingBottom());

      canvas.drawRoundRect(rectF,25,25, mPaint);

    }

    // 未覆盖的进度

    if(!noNeedBg) {

      floatstart = progressPosX;

      mPaint.setColor(mUnReachedBarColor);

      RectF rectF =newRectF(start,0- getPaddingTop() - getPaddingBottom(),

          mRealWidth + getPaddingRight() - radius, mReachedProgressBarHeight - getPaddingBottom());

      canvas.drawRoundRect(rectF,25,25, mPaint);

    }

    // 圆

    if(mIfDrawCircle) {

      mPaint.setColor(mCircleColor);

      canvas.drawCircle(progressPosX,0, radius, mPaint);

    }

    // 文本

    if(mIfDrawText) {

      mPaint.setColor(mTextColor);

      canvas.drawText(text, progressPosX - textWidth /2, -textHeight, mPaint);

    }

    canvas.restore();

  }

  /**

   * dp 2 px

   */

  protectedintdp2px(intdpVal) {

    return(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics());

  }

  /**

   * sp 2 px

   */

  protectedintsp2px(intspVal) {

    return(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, getResources().getDisplayMetrics());

  }

}

使用

在布局文件中加入:

 代码如下复制代码

    android:id="@+id/hpbwn"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:layout_margin="10dp"

    fun:progress_circle_color="#ff000000"

    fun:progress_reached_bar_height="20dp"

    fun:progress_reached_color="#FFFF4081"

    fun:progress_text_color="#ffffffff"

    fun:progress_text_size="14sp"

    fun:progress_unreached_bar_height="20dp"

    fun:progress_unreached_color="#ffBCB4E8"/>

progress_reached_bar_height:当前进度的高度
progress_unreached_bar_height:剩余进度的高度
progress_text_size:圆圈内文字的大小

注意:

当前进度和剩余进度的高度要一致,圆圈大小和圆圈内文字的大小要配合Java代码调整。

项目源码:

https://github.com/hfrommane/ProgressBarWithNumber

热门栏目