自定義Textview實現類似電池進度條的效果

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章