Android自定义控件之自定义进度条

Android自定义控件之自定义进度条_第1张图片

自定义控件的几个步骤:
1.在attrs.xml文件声明自定义属性。
2.在此类中通过TypedArray拿到自定义属性的值。
3.根据这些值完成onMeasure,onLayout()和onDraw()函数。
>
attrs.xml文件


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
        
        
    

直线进度条MyProgressBar

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.ProgressBar;

import com.example.yang.crazydemo.R;

/**
 * createtime:2019/8/12
 * author:Yang
 * describe:
 */
public class MyProgressBar extends ProgressBar {
    private static final int  DEFAULT_TEXT_SIZE=10;//sp
    private static final int  DEFAULT_TEXT_COLOR=0xFFFC00D1;
    private static final int  DEFAULT_COLOR_UNREACH=0XFFD3D6DA;
    private static final int  DEFAULT_COLOR_REACH=DEFAULT_TEXT_COLOR;
    private static final int  DEFAULT_HEIGHT_REACH=2;//dp
    private static final int  DEFAULT_HEIGHT_UNREACH=2;//dp
    private static final int  DEFAULT_TEXT_OFFSET=10;//dp



    protected int mTextColor=DEFAULT_TEXT_COLOR;
    protected int mTextSize=Sptopx(DEFAULT_TEXT_SIZE);
    protected int mTextOffset=Dptopx(DEFAULT_TEXT_OFFSET);
    protected int mReachColor=DEFAULT_COLOR_REACH;
    protected int mUnReachColor=DEFAULT_COLOR_UNREACH;
    protected int mReachHeight=Dptopx(DEFAULT_HEIGHT_REACH);
    protected int mUnReachHeight=Dptopx(DEFAULT_HEIGHT_UNREACH);


    protected Paint mpaint=new Paint();
    protected int mRealWidth;

    public MyProgressBar(Context context) {
        this(context,null);
    }
    public MyProgressBar(Context context,AttributeSet attrs) {
        this(context,attrs,0);
    }
    public MyProgressBar(Context context,AttributeSet attrs,int defStyle) {
        super(context,attrs,defStyle);
        ObtainStyleAttrs(attrs);
    }

    protected void ObtainStyleAttrs(AttributeSet attrs) {
        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.MyProgressBar);
        mTextSize=(int) typedArray.getDimension(R.styleable.MyProgressBar_progress_text_size, mTextSize);
        mReachColor=typedArray.getColor(R.styleable.MyProgressBar_progress_reach, mReachColor);
        mUnReachColor=typedArray.getColor(R.styleable.MyProgressBar_progress_unreach,mUnReachColor);
        mTextColor=typedArray.getColor(R.styleable.MyProgressBar_progress_text_color,mTextColor );
        mTextOffset= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_text_offset,mTextOffset);
        mUnReachHeight= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_unreach_height,mUnReachHeight);
        mReachHeight= (int) typedArray.getDimension(R.styleable.MyProgressBar_progress_reach_height,mReachHeight);
        typedArray.recycle();
        mpaint.setTextSize(mTextSize);
    }
    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthVal=MeasureSpec.getSize(widthMeasureSpec);
        int height=MeasureHeight(heightMeasureSpec);
        setMeasuredDimension(widthVal, height);
        mRealWidth=getMeasuredWidth()-getPaddingLeft()-getPaddingRight();

    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        canvas.save();
        canvas.translate(getPaddingLeft(), getHeight()/2);
        boolean NOneedUnreach=false;
        float radio=getProgress()*1.0f/getMax();
        String text=getProgress()+"%";
        float textWidth=mpaint.measureText(text);
        float ProgressX=radio*mRealWidth;
        if(ProgressX+textWidth>mRealWidth){
            ProgressX=mRealWidth-textWidth;
            NOneedUnreach=true;

        }
        float EndX=ProgressX-mTextOffset/2;
        //绘制reach
        if(EndX>0){
            mpaint.setColor(mReachColor);
            mpaint.setStrokeWidth(mReachHeight);
            canvas.drawLine(0, 0, EndX, 0, mpaint);
        }
        //绘制text
        mpaint.setColor(mTextColor);
        int y= (int) (-(mpaint.ascent()+mpaint.descent())/2);
        canvas.drawText(text, ProgressX, y,mpaint);
        //绘制Unreach

        if(!NOneedUnreach){
            mpaint.setColor(mUnReachColor);
            float start=ProgressX+mTextOffset/2+textWidth;
            mpaint.setStrokeWidth(mUnReachHeight);
            canvas.drawLine(start, 0,mRealWidth, 0, mpaint);
        }
        canvas.restore();
    }

    private int MeasureHeight(int heightMeasureSpec) {
        int result=0;
        int Mode=MeasureSpec.getMode(heightMeasureSpec);
        int Size=MeasureSpec.getSize(heightMeasureSpec);
        if(Mode==MeasureSpec.EXACTLY){
            result=Size;
        }else{
            int TextSize= (int) (mpaint.descent()-mpaint.ascent());
            result=getPaddingTop()+getPaddingBottom()+Math.max(Math.max(mReachHeight, mUnReachHeight)
                    , Math.abs(TextSize));
            if(Mode==MeasureSpec.AT_MOST){
                result=Math.min(result, Size);
            }
        }
        return result;
    }

    public  int Dptopx(int dpval){
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                dpval, getResources().getDisplayMetrics());
    }
    public int Sptopx(int spval){
        return (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, spval,
                getResources().getDisplayMetrics());
    }

}

圆形进度条MyRoundProgressBar

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;

import com.example.yang.crazydemo.R;

/**
 * createtime:2019/8/13
 * author:Yang
 * describe:圆形的进度条
 */
public class MyRoundProgressBar extends MyProgressBar {
    private int mRadius=Dptopx(30);
    private int mMaxPaintWidth;
    public MyRoundProgressBar(Context context) {
        this(context,null);
    }
    public MyRoundProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyRoundProgressBar(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mReachHeight= (int) (2.5f*mUnReachHeight);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyRoundProgressBar);
        mRadius= (int) typedArray.getDimension(R.styleable.MyRoundProgressBar_progress_radius, mRadius);
        typedArray.recycle();
        mpaint.setAntiAlias(true);
        mpaint.setDither(true);
        mpaint.setStyle(Paint.Style.STROKE);
        mpaint.setStrokeCap(Paint.Cap.ROUND);
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              mMaxPaintWidth=Math.max(mReachHeight, mUnReachHeight);
              int expect=2*mRadius+mMaxPaintWidth+getPaddingLeft()+getPaddingRight();
              int height=resolveSize(expect, heightMeasureSpec);
              int width=resolveSize(expect,widthMeasureSpec);
              int realWidth=Math.min(height, width);
              mRadius=(realWidth-getPaddingRight()-getPaddingLeft()-mMaxPaintWidth)/2;
              setMeasuredDimension(realWidth, realWidth);
    }


    @Override
    protected synchronized void onDraw(Canvas canvas) {
        String text=getProgress()+"%";
        int textwidth= (int) mpaint.measureText(text);
        int textheight=(int)(mpaint.descent()+mpaint.ascent())/2;
        canvas.save();
        canvas.translate(getPaddingLeft()+mMaxPaintWidth/2, getPaddingTop()+mMaxPaintWidth/2);
        mpaint.setStyle(Paint.Style.STROKE);
        //绘制unReachbar
        mpaint.setColor(mUnReachColor);
        mpaint.setStrokeWidth(mUnReachHeight);
        canvas.drawCircle(mRadius, mRadius,mRadius , mpaint);
        //绘制Reachbar
        mpaint.setColor(mReachColor);
        mpaint.setStrokeWidth(mReachHeight);
        float sweepAngle=getProgress()*1.0f/getMax()*360;
        canvas.drawArc(new RectF(0,0,2*mRadius,2*mRadius)
                , 0, sweepAngle, false,mpaint );
        //绘制Text
        mpaint.setStyle(Paint.Style.FILL);
        mpaint.setColor(mTextColor);
        canvas.drawText(text, mRadius-textwidth/2, mRadius-textheight, mpaint);
        canvas.restore();

    }
}

布局代码(view是包名)



    
    
    
    


Activity使用代码

import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import view.MyProgressBar;
import view.MyRoundProgressBar;


public class ProgressActivity extends AppCompatActivity {
private MyProgressBar progressBarone;
private MyRoundProgressBar myRoundProgressBar;
private MyProgressBar progressBartwo;
private MyRoundProgressBar myRoundProgressBartwo;
private static final int UPDATA_MSG=0x111;
private Handler handler=new Handler(){
    @Override
    public void handleMessage(Message msg) {
        int ProgressX=progressBarone.getProgress();
        int ProgressY=progressBartwo.getProgress();
        progressBarone.setProgress(++ProgressX);
        myRoundProgressBar.setProgress(++ProgressX);
        progressBartwo.setProgress(--ProgressY);
        myRoundProgressBartwo.setProgress(--ProgressY);
        while(progressBarone.getProgress()>100){
            removeMessages(UPDATA_MSG);
        }
        while (progressBartwo.getProgress()<0){
            removeMessages(UPDATA_MSG);
        }
        handler.sendEmptyMessageDelayed(UPDATA_MSG, 100);
    }
};
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_progress);
        progressBarone=findViewById(R.id.myprogress_one);
        myRoundProgressBar=findViewById(R.id.myprogress_three);
        progressBartwo=findViewById(R.id.myprogress_two);
        myRoundProgressBartwo=findViewById(R.id.myprogress_four);
        Message msg=new Message();
        msg.what=1;
        handler.sendMessage(msg);

    }
}

演示效果图

Android自定义控件之自定义进度条_第2张图片

你可能感兴趣的:(Android,CustomView,Android自定义进度条)