自定义进度条实现大体流程
1、自定义属性声明(attrs文件) 2、自定义属性获取 3、测量(onMeasure) 4、绘制(onDraw)代码:
attrs文件:
<!-- 自定义声明 -->
<attr name="progress_unreach_color" format="color"></attr> <attr name="progress_unreach_height" format="dimension"></attr> <attr name="progress_reach_color" format="color"></attr> <attr name="progress_reach_height" format="dimension"></attr> <attr name="progress_text_color" format="color"></attr> <attr name="progress_text_size" format="dimension"></attr> <attr name="progress_text_offset" format="dimension"></attr> <!-- 自定义使用 --> <declare-styleable name="ProgressbarView"> <attr name="progress_unreach_color"></attr> <attr name="progress_unreach_height"></attr> <attr name="progress_reach_color"></attr> <attr name="progress_reach_height"></attr> <attr name="progress_text_color"></attr> <attr name="progress_text_size"></attr> <attr name="progress_text_offset"></attr> </declare-styleable>布局文件:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:hyman="http://schemas.android.com/apk/res/com.Horizontal.horizontalprogressbar" android:layout_width="match_parent" android:layout_height="match_parent" ><LinearLayout
android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" ><com.Horizontal.view.ProgressbarView
android:id="@+id/progress01" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dip" hyman:progress_reach_color="#f00" hyman:progress_text_color="#f00" hyman:progress_unreach_color="#000" android:background="#d1d3d7" android:padding="10dip" android:progress="0" /> <com.Horizontal.view.RoundProgressbar android:id="@+id/progress02" android:layout_width="match_parent" android:layout_height="wrap_content" hyman:progress_reach_color="#f3d4e3" hyman:progress_text_color="#f00" hyman:progress_unreach_color="#000" android:layout_marginTop="30dp" hyman:rudio="80dp" android:padding="10dip" android:progress="0" /> </LinearLayout></ScrollView>
ProgressbarView文件:
package com.Horizontal.view;
import com.Horizontal.horizontalprogressbar.R;
import android.content.Context;
import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.PaintFlagsDrawFilter;import android.util.AttributeSet;import android.util.TypedValue;import android.widget.ProgressBar;public class ProgressbarView extends ProgressBar {
private static final int DEFAULT_TEXT_SIZE = 10;// 字体大小 sp private static final int DEFAULT_TEXT_COLOR = 0xFC00D1; private static final int DEFAULT_REACH_HEIGHT = 3;// 左进度条高度 dp private static final int DEFAULT_REACH_COLOR = DEFAULT_TEXT_COLOR; private static final int DEFAULT_UNREACH_HEIGHT = 2;// 右进度条高度 dp private static final int DEFAULT_UNREACH_COLOR = 0xD3D6D1; private static final int DEFAULT_TEXT_OFFSET = 10;// 做进度条与文字的距离 dpprotected int mTextSize = sp2px(DEFAULT_TEXT_SIZE);
protected int mTextColor = DEFAULT_TEXT_COLOR; protected int mReachHeight = dp2px(DEFAULT_REACH_HEIGHT); protected int mReachColor = DEFAULT_REACH_COLOR; protected int mUnReachHeight = dp2px(DEFAULT_UNREACH_HEIGHT); protected int mUnReachColor = DEFAULT_UNREACH_COLOR; protected int mTextOffset = dp2px(DEFAULT_TEXT_OFFSET);protected Paint mPaint = new Paint();
// 控件的宽度 private int mRealWidth;public ProgressbarView(Context context) {
this(context, null); }public ProgressbarView(Context context, AttributeSet attrs) {
this(context, attrs, 0); }public ProgressbarView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle); obtainStyledAttrs(attrs); }/** 获取自定义属性 **/
private void obtainStyledAttrs(AttributeSet attrs) { // 获取attr文件中的styleable(ProgressbarView) TypedArray ta = getContext().obtainStyledAttributes(attrs, R.styleable.ProgressbarView); // 获取自定义属性和默认值 mTextSize = (int) ta.getDimension( R.styleable.ProgressbarView_progress_text_size, mTextSize); mTextColor = ta.getColor( R.styleable.ProgressbarView_progress_text_color, mTextColor); mReachHeight = (int) ta .getDimension( R.styleable.ProgressbarView_progress_reach_height, mReachHeight); mReachColor = ta.getColor( R.styleable.ProgressbarView_progress_reach_color, mReachColor); mUnReachHeight = (int) ta.getDimension( R.styleable.ProgressbarView_progress_unreach_height, mUnReachHeight); mUnReachColor = ta.getColor( R.styleable.ProgressbarView_progress_unreach_color, mUnReachColor); mTextOffset = (int) ta.getDimension( R.styleable.ProgressbarView_progress_text_offset, mTextOffset);ta.recycle();
mPaint.setTextSize(mTextSize); }/** 宽度和高度的测量 **/
@Override protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 拿宽度的模式 // int widthMode = MeasureSpec.getMode(widthMeasureSpec); // 宽度的值(横向精度条要给明确值,所以不需要判断) int widthVal = MeasureSpec.getSize(widthMeasureSpec); int heigth = MeasureSpecHeigth(heightMeasureSpec); setMeasuredDimension(widthVal, heigth); // 实际绘画的宽度 mRealWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight(); }/** 高度测量 **/
private int MeasureSpecHeigth(int heightMeasureSpec) { int result = 0; int mode = MeasureSpec.getMode(heightMeasureSpec); int size = MeasureSpec.getSize(heightMeasureSpec); // EXACTLY 父结点要求其子节点的大小指定为某个确切的值。其子节点以及其他子孙结点都需要适应该大小。 if (mode == MeasureSpec.EXACTLY) { result = size; } else { int textHeigth = (int) (mPaint.descent() - mPaint.ascent()); result = getPaddingTop() + getPaddingBottom() + Math.max(Math.max(mReachHeight, mUnReachHeight), Math.abs(textHeigth)); // AT_MOST 父结点要求其子节点的大小不能超过某个最大值,其子节点以及其他子孙结点的大小都需要小于这个值 if (mode == MeasureSpec.AT_MOST) { result = Math.min(result, size); } }return result;
}/** 画控件 **/
@Override protected synchronized void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.save(); // 抗锯齿 canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); // 设置画布的原点 canvas.translate(getPaddingLeft(), getHeight() / 2); // /draw reach boolean noNeedUnreach = false; String text = getProgress() + "%"; int textWidth = (int) mPaint.measureText(text); float radio = getProgress() * 1.0f / getMax(); float progressX = radio * mRealWidth; if (textWidth + progressX > mRealWidth) { progressX = mRealWidth - textWidth; noNeedUnreach = true; }float endX = progressX - mTextOffset / 2;
if (endX > 0) { mPaint.setColor(mReachColor); mPaint.setStrokeWidth(mReachHeight); canvas.drawLine(0, 0, endX, 0, mPaint); }// draw text
mPaint.setColor(mTextColor); int y = (int) (-(mPaint.descent() + mPaint.ascent()) / 2); canvas.drawText(text, progressX, y, mPaint); // draw unreach bar if (!noNeedUnreach) { float start = progressX + mTextOffset / 2 + textWidth; mPaint.setColor(mUnReachColor); mPaint.setStrokeWidth(mUnReachHeight); canvas.drawLine(start, 0, mRealWidth, 0, mPaint); }canvas.restore();
}/** dp转px **/
protected int dp2px(int dpVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpVal, getResources().getDisplayMetrics()); }/** sp转px **/
protected int sp2px(int spVal) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spVal, getResources().getDisplayMetrics()); }}MainActivity:
package com.Horizontal.horizontalprogressbar;
import com.Horizontal.view.ProgressbarView;
import com.Horizontal.view.RoundProgressbar;import android.os.Bundle;
import android.os.Handler;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {
private ProgressbarView progressbarView;// private RoundProgressbar roundProgressbar; private static final int MSG_UPDATE = 0X110;@Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressbarView = (ProgressbarView) findViewById(R.id.progress01);// roundProgressbar=(RoundProgressbar) findViewById(R.id.progress02); handler.sendEmptyMessage(MSG_UPDATE); }private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) { int progress = progressbarView.getProgress();// roundProgressbar.setProgress(++progress); progressbarView.setProgress(++progress); if (progress >= 100) { handler.removeMessages(MSG_UPDATE); } handler.sendEmptyMessageDelayed(MSG_UPDATE, 100); }; };}
源码下载:链接: 密码: whs7