第一次寫博客,格式什麼的見諒。
先上個效果圖
如上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)繪製的時候
是從上到下的,順序正好相反,算起來就比較麻煩一點。