第一次写博客,格式什么的见谅。
先上个效果图
如上100%分割成十个柱体 每个代表 10% 每个柱体又分了10等分。中间显示数值
代码很简单 直接贴上了
1,自定义的属性
在attrs.xml中添加
<declare-styleable name="CustomProgressBar">
<attr name="lowColor" format="color" />
<attr name="minColor" format="color" />
<attr name="normalColor" format="color" />
<attr name="rate" format="integer" />
</declare-styleable>
2,继承TextView主要是复写onDraw方法
/**
* Created by zjs on 2016/6/10.
*/
public class CustomProgressBar1 extends TextView {
private int lowColor;
private int midColor;
private int normalColor;
private Paint mPaint;
/**百分比*/
private int mRate,tempRate;
/***百分比的数值*/
// private int mRateText;
/**外边框的宽度*/
private int mBorder=16;
/***柱体的宽**/
private int mW;
/***间隔水平距离*/
private int mDividerW=20;
/***柱体个数默认10**/
private int mSum =10;
/***分割后有一个未完整部分 均分到 柱体的左右两边,使柱体居中*/
private int mRemain;
/***100%分割成十个柱体 每个代表 10% 那么有且最多只有一个是不满的
* 如76% 那么前7(mCount)个是满的都是 10% 第八个只有6成满 **/
private int mCount;
/***不满的那一格的数值*/
private int mBoundRate;
/***更新动画标识*/
private static final int MSG_PROGRESS_UPDATE = 0x100000;
private static final int MSG_PROGRESS_END = 0x110000;
/***动画效果*/
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
tempRate=msg.arg1;
if (msg.what == MSG_PROGRESS_UPDATE ){
if (tempRate >= mRate ) {
setRate();
// mHandler.sendMessage(mHandler.obtainMessage(MSG_PROGRESS_END));
mHandler.removeMessages(MSG_PROGRESS_UPDATE);
}else{
setTempRate(msg.arg1);
}
}else if(msg.what == MSG_PROGRESS_END) {
///用这个去停止比较规范 影响百分比的绘制 弃用
// isDrawRate=true;
// setRate();
}
}
};
public CustomProgressBar1(Context context) {
super(context);
}
public CustomProgressBar1(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs,0 );
}
public CustomProgressBar1(Context context, AttributeSet attrs,
int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs, defStyleAttr);
}
private void init(Context context,AttributeSet attrs,int defStyle){
/**
* 获得我们所定义的自定义样式属性
*/
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CustomProgressBar, defStyle, 0);
lowColor = a.getColor(R.styleable.CustomProgressBar_lowColor, Color.RED);
midColor = a.getColor(R.styleable.CustomProgressBar_minColor, Color.YELLOW);
normalColor = a.getColor(R.styleable.CustomProgressBar_normalColor, Color.BLUE);
mRate =a.getInt(R.styleable.CustomProgressBar_rate,0);
mCount=mRate/mSum;
mBoundRate=mRate%mSum;
a.recycle();
mPaint = new Paint();
mPaint.setColor(normalColor);
}
/***设置百分比**/
public void setRate(int rate){
mRate=rate;
mCount=mRate/mSum;
mBoundRate=mRate%mSum;
this.invalidate();
mHandler.sendMessage(mHandler.obtainMessage(MSG_PROGRESS_UPDATE));
}
private void setRate(){
mCount=mRate/mSum;
mBoundRate=mRate%mSum;
this.invalidate();
}
private void setTempRate(int rate ){
mCount=rate/mSum;
mBoundRate=rate%mSum;
this.invalidate();
Message msg =mHandler.obtainMessage(MSG_PROGRESS_UPDATE);
msg.arg1=rate+1;
mHandler.sendMessageDelayed( msg,30);
}
@Override
protected void onDraw(Canvas canvas) {
drawRectBorder(canvas);
drawRects(canvas);
drawRate(canvas,tempRate);
super.onDraw(canvas);
}
/***绘制10个柱体*/
private void drawRects(Canvas canvas){
Paint paint = new Paint();
if (mCount==0){
paint.setColor(lowColor);
}else if(mCount==1){
paint.setColor(midColor);
}else{
paint.setColor(normalColor);
}
mW=(getWidth()-mDividerW-mBorder)/ mSum -mDividerW;
mRemain=mBorder/2;
float x=0f;
for (int i = 0; i < mCount ; i++) {
x=getWidth()-((mW+mDividerW)*i+mDividerW+mRemain);
canvas.drawRect( x-mW ,mBorder, x, getHeight()-mBorder, paint);
}
/***最后一个可能没填满单独绘制*/
x=getWidth()-((mW+mDividerW)*mCount+1+mDividerW+mRemain);
int y=getHeight() - (( getHeight()-mBorder -mBorder)*mBoundRate/mSum)-mBorder;
canvas.drawRect( x-mW ,y, x , getHeight()-mBorder, paint);
}
/***绘制外边框**/
private void drawRectBorder(Canvas canvas){
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), paint);
//设置空心Style
mPaint.setStyle(Paint.Style.STROKE);
//设置空心边框的宽度
mPaint.setStrokeWidth(mBorder);
//绘制空心矩形
canvas.drawRect(0, 0, getWidth(), getHeight(), mPaint);
}
/***绘制百分比的文本*/
private void drawRate(Canvas canvas,int rate ){
Paint paint = new Paint();
//去锯齿
paint.setAntiAlias(true);
//设置颜色
paint.setColor(Color.WHITE);
paint.setTextSize(getTextSize());
//绘制文本
canvas.drawText(rate+"%", getWidth()/2, getHeight()/2+mBorder, paint);
}
}
3使用自定义的进度条
<com.example.test.CustomProgressBar1
android:id="@+id/main_custom_pb1"
android:layout_width="match_parent"
android:layout_marginTop="20dp"
android:layout_below="@+id/main_custom_pb"
android:layout_height="30dp"
android:textSize="16sp"
android:padding="5dp"
custom:minColor="#ffff00"
android:textColor="@android:color/white"
custom:normalColor="#f52f89"
custom:lowColor="#ff0000"
custom:rate="92"/>
mCustomProgressBar1= (CustomProgressBar1) findViewById(R.id.main_custom_pb1);
mCustomProgressBar.setRate(81);
4总结
这个效果很简单,没什么技术难点,要注意的是View的坐标系。屏幕左上角为原点(0,0)绘制的时候
是从上到下的,顺序正好相反,算起来就比较麻烦一点。