简单实现自定义控件圆形进度条

首先在res/values下建一个attrs.xml,里面内容为:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyProgressRound">
        <!--format表示类型-->
       <!--progressColor表示进度条的颜色-->
        <attr name="progressColor" format="color" />
        <!--textSize圆环中间的文本大小-->
        <attr name="textSize" format="dimension" />
        <!--ringSize弧的宽度-->
        <attr name="ringSize" format="dimension" />
        <!--radiuSize外圆的半径-->
        <attr name="radiuSize" format="dimension" />
    </declare-styleable>
</resources>

接着在要显示的布局main.xml:

<?xml version="1.0" encoding="utf-8"?>
<!--
    xmlns:attrs="http://schemas.android.com/apk/res-auto"
    是引用刚才创建的xml文件,attrs表示一个名字,随意起,不用和之前创建的xml的名字一样
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:attrs="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.bwie.circleprogreebar.MainActivity">
    <!--attrs:ringSize="10dp" 有时候快捷键不出来,也只能手敲了-->
    <com.bwie.circleprogreebar.CircleView
        android:id="@+id/cv"
        attrs:ringSize="10dp"
        attrs:progressColor="#afa"
        attrs:radiuSize="100dp"
        attrs:textSize="20dp"
        android:background="#f00"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

 

public class CircleView extends View {
    Paint paint;//画笔
    private int mProgress=0;//进度条的进度
    private int mCountProgress=0;//圆环中间的文本表示进度条的进度百分比

    private float mRadiuSize = 0;//外圆的半径
    private float mRingSize = 0;//弧的宽度
    private float mTextSize = 0;//圆环中间的文本大小
    private int mProgressColor = 0;//表示进度条的颜色

    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        getCustomAttr(context,attrs);//attrs为控件中的属性集合
        init();
    }

    private void getCustomAttr(Context context, AttributeSet attrs) {
        TypedArray array=context.obtainStyledAttributes(attrs,R.styleable.MyProgressRound);
        //第一个参数为控件中输入的值,第二个参数为默认值
        mRadiuSize=array.getDimension(R.styleable.MyProgressRound_radiuSize,100);
        mRingSize=array.getDimension(R.styleable.MyProgressRound_ringSize,10);
        mTextSize=array.getDimension(R.styleable.MyProgressRound_textSize,10);
        mProgressColor=array.getColor(R.styleable.MyProgressRound_progressColor,Color.BLACK);
    }

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        paint=new Paint();//创建画笔对象
        paint.setAntiAlias(true);//抗锯齿
    }

    
    //warpcontent类型 MeasureSpec.AT_MOST
    //matchparent类型 或者具体的长度 100dp 200dp   MeasureSpec.EXACTLY
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);//获取宽的模式
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);//获取高的模式
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);//获取输入的宽的值
        int heightSize=MeasureSpec.getSize(heightMeasureSpec);//获取输入的高的值

        int width=0;
        int height=0;
        if (widthMode==MeasureSpec.AT_MOST){
            width=(int)(mRadiuSize*2);
        }else {
            width=Math.max(widthSize,(int)(mRadiuSize*2));
        }
        if (heightMode==MeasureSpec.AT_MOST){
            height=(int)(mRadiuSize*2);
        }else {
            height=Math.max(heightSize,(int)(mRadiuSize*2));
        }
        //给自定义控件设置宽高
        setMeasuredDimension(width,height);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        paint.setStrokeWidth(0);
        paint.setColor(Color.BLACK);
        paint.setStyle(Paint.Style.STROKE);
        int ring=getMeasuredWidth()/2;
        canvas.drawCircle(ring,ring,mRadiuSize,paint);
        canvas.drawCircle(ring,ring,mRadiuSize-mRingSize,paint);

        paint.setTextSize(mTextSize);
        String text=mCountProgress+"%";
        float textWidth=paint.measureText(text);
        canvas.drawText(text,ring-textWidth/2,ring+textWidth/2,paint);
        RectF rectF=new RectF(ring-mRadiuSize+mRingSize/2,ring-mRadiuSize+mRingSize/2,ring+mRadiuSize-mRingSize/2,ring+mRadiuSize-mRingSize/2);
        paint.setStrokeWidth(mRingSize);
        paint.setColor(mProgressColor);
        canvas.drawArc(rectF,0,mProgress,false,paint);

    }
    public void setProgress(int progress){
        mProgress=progress;
        mCountProgress=progress*100/360;
        invalidate();
    }
}

 

public class MainActivity extends AppCompatActivity {
    CircleView cv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        cv= (CircleView) findViewById(R.id.cv);
        new AsyncTask<String,Integer,String>(){
            @Override
            protected String doInBackground(String... strings) {
                for (int i=0;i<=360;i++){
                    SystemClock.sleep(100);
                    publishProgress(i);
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(Integer... values) {
                super.onProgressUpdate(values);
                cv.setProgress(values[0]);
            }
        }.execute();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值