自定義view,顯示進度標點及進度數值,外進度框和內進度條。
自定義view類
package com.sample.util;
import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.RectF; import android.util.AttributeSet; import android.util.Log; import android.view.View; import com.gj.gateway.R; public class HProgressBar extends View { private final String TAG = "HProgressBar"; private int mProgress_outline_color = 0xFFFFFFFF;//外邊框顏色 private int mProgress_color = 0xFFFFFFFF; //進度條顏色 private int mProgress_circle_color = 0xFFD1F4DE; //圓圈顏色 private int mProgress_text_color = 0xFFFFFFFF; //進度字體顏色 private int mProgress_text_bg_color = 0x50FFFFFF; //進度背景顏色 private float mProgress_circle_height = 56;// 56; //圓圈高度 private float mProgress_height = 40;// 25; //progress高度 private float mProgress_bar_height = 30; //progress進度條高度 private float mProgress_text_height = 35; //進度文字高度 private float mProgress_text_paddingH = 25; //進度文字左右padding private float mProgress_text_paddingV = 0; //進度文字上下pading private float mProgress_text_size = 32; //進度文字字體大小 private float mMaxProgress = 100; private volatile float mProgress_progress_bar = 0; private int mProgressWidth; private Paint mOutLinePaint; private Paint mProgressPaint; private Paint mCirClePaint; private Paint mTextPain; private Paint mTextBgPain; public HProgressBar(Context context) { super(context); Log.d(TAG, "HProgressBar: 1"); } public HProgressBar(Context context, AttributeSet attrs) { super(context, attrs); Log.d(TAG, "HProgressBar: 2"); initDefStyleAttr(attrs); mOutLinePaint = new Paint(); mOutLinePaint.setColor(mProgress_outline_color); mOutLinePaint.setAntiAlias(true); mOutLinePaint.setStrokeWidth(2); mOutLinePaint.setStyle(Paint.Style.STROKE); //設置空心 mProgressPaint = new Paint(); mProgressPaint.setColor(mProgress_color); mProgressPaint.setAntiAlias(true); mCirClePaint = new Paint(); mCirClePaint.setColor(mProgress_circle_color); mCirClePaint.setAntiAlias(true); mTextBgPain = new Paint(); mTextBgPain.setColor(mProgress_text_bg_color); mTextBgPain.setAntiAlias(true); mTextPain = new Paint(); mTextPain.setColor(mProgress_text_color); mTextPain.setAntiAlias(true); mTextPain.setTextSize(mProgress_text_size); mTextPain.setTextAlign(Paint.Align.CENTER); mTextPain.setTextSize(mProgress_text_size); } public HProgressBar(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); Log.d(TAG, "HProgressBar: 3"); } public HProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); Log.d(TAG, "HProgressBar: 4"); } private void initDefStyleAttr(AttributeSet attrs) { final TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.HProgress); mProgress_outline_color = attributes.getColor(R.styleable.HProgress_hProgress_outline_color, mProgress_outline_color); mProgress_color = attributes.getColor(R.styleable.HProgress_hProgress_color, mProgress_color); mProgress_circle_color = attributes.getColor(R.styleable.HProgress_hProgress_circle_color, mProgress_circle_color); mProgress_text_color = attributes.getColor(R.styleable.HProgress_hProgress_text_color, mProgress_text_color); mProgress_text_bg_color = attributes.getColor(R.styleable.HProgress_hProgress_text_bg_color, mProgress_text_bg_color); mProgress_circle_height = (int) attributes.getDimension(R.styleable.HProgress_hProgress_circle_height, mProgress_circle_height); mProgress_height = (int) attributes.getDimension(R.styleable.HProgress_hProgress_height, mProgress_height); mProgress_bar_height = (int) attributes.getDimension(R.styleable.HProgress_hProgress_bar_height, mProgress_bar_height); mProgress_text_height = (int) attributes.getDimension(R.styleable.HProgress_hProgress_text_height, mProgress_text_height); mProgress_text_size = (int) attributes.getDimension(R.styleable.HProgress_hProgress_text_size, mProgress_text_size); mProgress_text_paddingH = (int) attributes.getDimension(R.styleable.HProgress_hProgress_text_paddingH, mProgress_text_paddingH); mProgress_text_paddingV = (int) attributes.getDimension(R.styleable.HProgress_hProgress_text_paddingV, mProgress_text_paddingV); mProgress_progress_bar = attributes.getInteger(R.styleable.HProgress_hProgress_progress_bar, (int)mProgress_progress_bar); mMaxProgress = attributes.getInteger(R.styleable.HProgress_hProgress_maxProgress, (int) mMaxProgress); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); mProgressWidth = MeasureSpec.getSize(widthMeasureSpec); setMeasuredDimension(mProgressWidth, (int )(mProgress_text_height + mProgress_circle_height)); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Rect rect = new Rect(); mTextPain.getTextBounds(String.valueOf(getProgress()), 0, String.valueOf(getProgress()) .length(),rect); int w = rect.width(); int h = rect.height(); float spaceA = (mProgress_circle_height - mProgress_height) / 2; float spaceB = (mProgress_height - mProgress_bar_height) / 2; float progressMargin = mProgress_circle_height / 2; //長度變化范圍等於控件長度減去兩邊的邊距和空隙,由於是圓角進度條,還要減去內進度條的高度,即內進度條兩邊半圓的長度 float changeRange = mProgressWidth - (progressMargin + spaceB) * 2 - mProgress_bar_height; float startPoint = progressMargin + spaceB; float circleX = startPoint + mProgress_bar_height / 2 + changeRange * getProgress() / mMaxProgress; float textStartX; float textEndX; if (circleX - w / 2 - mProgress_text_paddingH < 0) { textStartX = 0; textEndX = textStartX + w + mProgress_text_paddingH * 2; } else if (circleX + w / 2 + mProgress_text_paddingH >= mProgressWidth) { textStartX = mProgressWidth - mProgress_text_paddingH * 2 - w; textEndX = mProgressWidth; } else { textStartX = circleX - w / 2 - mProgress_text_paddingH; textEndX = circleX + w / 2 + mProgress_text_paddingH; } //畫數字背景框 RectF rectF2 = new RectF(textStartX, mProgress_circle_height, textEndX, mProgress_circle_height + mProgress_text_height); canvas.drawRoundRect(rectF2, mProgress_text_height / 2, mProgress_text_height / 2, mTextBgPain); //畫數字進度 Paint.FontMetrics fontMetrics = mTextPain.getFontMetrics(); canvas.drawText((int)getProgress() + "", (textStartX + textEndX) / 2, mProgress_circle_height + mProgress_text_height / 2 + (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent, mTextPain); //畫progressBar 外邊 RectF rectF = new RectF(progressMargin, spaceA,mProgressWidth - progressMargin, mProgress_height + spaceA); canvas.drawRoundRect(rectF, mProgress_height / 2, mProgress_height / 2, mOutLinePaint); //畫progressBar 內進度條 RectF rectF1 = new RectF(startPoint, spaceA + spaceB, startPoint + mProgress_bar_height + changeRange * getProgress()/mMaxProgress, mProgress_bar_height + spaceB + spaceA); canvas.drawRoundRect(rectF1, mProgress_bar_height / 2, mProgress_bar_height / 2, mProgressPaint); //畫圓 canvas.drawCircle(circleX, mProgress_circle_height / 2, mProgress_circle_height / 2, mCirClePaint); } public int getProgress() { return (int)mProgress_progress_bar; } public void setProgress(int progress) { if (progress > mMaxProgress) { throw new RuntimeException("progress mast less than mMaxProgress"); } mProgress_progress_bar = progress; postInvalidate(); } public void setmMaxProgress(int maxProgress) { this.mMaxProgress = maxProgress; } }
資源文件中attrs.xml對應定義
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="HBLevelView"> <attr name="startProgress" format="float|reference" /> <attr name="scurrProgress" format="float|reference" /> <attr name="endProgress" format="float|reference" /> <attr name="progressTextSize" format="reference|dimension" /> <attr name="backColor" format="color|reference" /> <attr name="foreColor" format="color|reference" /> <attr name="textColor" format="color|reference" /> <attr name="rectCorn" format="dimension|reference" /> </declare-styleable> <declare-styleable name="HProgress"> <!--外邊框顏色--> <attr name="hProgress_outline_color" format="color" /> <!--進度條顏色--> <attr name="hProgress_color" format="color" /> <!--圓圈顏色--> <attr name="hProgress_circle_color" format="color" /> <!--進度字體顏色--> <attr name="hProgress_text_color" format="color" /> <!--進度背景顏色--> <attr name="hProgress_text_bg_color" format="color" /> <!--圓圈高度--> <attr name="hProgress_circle_height" format="dimension" /> <!--progress高度--> <attr name="hProgress_height" format="dimension" /> <!--progress進度條高度--> <attr name="hProgress_bar_height" format="dimension" /> <!--進度文字高度--> <attr name="hProgress_text_height" format="dimension" /> <!--進度文字字體大小--> <attr name="hProgress_text_size" format="dimension" /> <!--進度文字橫向padding--> <attr name="hProgress_text_paddingH" format="dimension" /> <!--進度文字縱向padding--> <attr name="hProgress_text_paddingV" format="dimension" /> <!--進度值--> <attr name="hProgress_progress_bar" format="integer" /> <attr name="hProgress_maxProgress" format="integer" /> </declare-styleable> </resources>
如果想使用該進度條,可以將這兩個文件移入到工程目錄中,在布局文件中使用自定義類:
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal"> <com.sample.util.HProgressBar android:id="@+id/hprogress_bar_register" android:layout_width="@dimen/d_885dp" android:layout_height="@dimen/d_40dp" android:layout_marginTop="@dimen/d_100dp" /> </LinearLayout>
操作控件
private HProgressBar mHProgressBar; .... mHProgressBar = (HProgressBar)findViewById(R.id.hprogress_bar_register); .... mHProgressBar.setProgress(100);