自定义View实心圆和圆环

来源:互联网 发布:廉价口红知乎 编辑:程序博客网 时间:2024/05/10 15:13
1.1、添加在vules中的Color中<declare-styleable name="ProgressView">        <!--circleColor 设置圆形边框的颜色 sweepColor设置扇形变换的颜色        startAngle 设置起始角度 sweepStep 设置变换的步长-->        <attr name="circleColor" format="color|reference"></attr>        <attr name="sweepColor" format="color|reference"></attr>        <attr name="startAngle" format="integer"></attr>        <attr name="sweepStep" format="integer"></attr>        <attr name="padding" format="integer"></attr>    </declare-styleable>1.2、布局  <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:onClick="onPlay"        android:text="点击自定义View"/>    <com.baway.www.circleviewdemo.ProgressView        android:layout_width="260dp"        android:layout_height="260dp"        android:id="@+id/onPro"/>

1、代码实现

public class ProgressView extends View {    private int sweepStep = 10;//扇形变换的步长(就是角度)    private int padding = 15;//外边框距离扇形的距离 填充    private int circleColor = Color.YELLOW;//边框的颜色    private int sweepColor = Color.GREEN;//扇形颜色    private int startAngle = 90;//起始角度    //设置外边框圆的边框粗细    private int storke = 20;    private int sweepAngle = 0;//扫过的角度    private static final int DEFAULT_WIDTH = 200;    private static final int DEFAULT_HEIGHT = 200;    public ProgressView(Context context) {        super(context);    }    //如果要在xml文件中使用该自定义控件,则必须重写两个参数的构造函数    //因为我们使用自定义的属性的时候,会默认传递过来一个AttributeSet集合    public ProgressView(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.ProgressView);        if (array != null) {            //获取我们在xml中设置的各个自定义属性            sweepStep = array.getInteger(R.styleable.ProgressView_sweepStep, sweepStep);            padding = array.getInteger(R.styleable.ProgressView_padding, padding);            circleColor = array.getColor(R.styleable.ProgressView_circleColor, circleColor);            sweepColor = array.getColor(R.styleable.ProgressView_sweepColor, sweepColor);            startAngle = array.getInteger(R.styleable.ProgressView_startAngle, startAngle);            //回收TypeArray资源            array.recycle();        }    }    //先绘制外边框 --内部扇形    int one = 360;    int two = 360;    int three = 360;    int fore =360;    @Override    protected void onDraw(Canvas canvas) {        Paint mPaint = new Paint();        mPaint.setAntiAlias(true); //设置抗锯齿        //绘制外层的圆框        mPaint.setColor(circleColor);        mPaint.setStrokeWidth(storke);        mPaint.setStyle(Paint.Style.STROKE);//设置圆形为空心的圆        //这里我们得到控件的Height和Width,根据Heigh和Width来确定圆心的位置,来绘制外层圆        canvas.drawCircle(getWidth() / 2, getWidth() / 2, getWidth() / 2 - storke / 2, mPaint);        // Log.d("tag", "onDraw: "+getWidth());        invalidate();//请求重新绘制view         //绘制内部的扇形        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);        mPaint.setColor(sweepColor);        RectF rectF1 = new RectF(one,two,three,fore);        canvas.drawArc(rectF1, 360f, 360f, true, mPaint);        one = one -2;        two = two - 2;        three=three+2;        fore=fore+2;        one = one<(padding + storke)?(padding + storke):one;        two = two<(padding + storke)?(padding + storke):two;        three = three>(getWidth() - padding - storke)?(getWidth() - padding - storke):three;        fore = fore>(getWidth() - padding - storke)?(getWidth() - padding - storke):fore;        invalidate();//重绘view    }    //因为我们是继承的View来自定义的View,所以onMeasure()方法要重写    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int wMode = MeasureSpec.getMode(widthMeasureSpec);        int hMode = MeasureSpec.getMode(heightMeasureSpec);        int wSize = MeasureSpec.getSize(widthMeasureSpec);        int hSize = MeasureSpec.getSize(heightMeasureSpec);        //因为绘制的是圆,所以判断一下高度或者宽度中的一个就可以。        switch (wMode) {            case MeasureSpec.AT_MOST://android:layout_width="warp_content"                //获取屏幕像素                float density = getResources().getDisplayMetrics().density;                wSize = (int) (DEFAULT_WIDTH * density);                hSize = (int) (DEFAULT_HEIGHT * density);                break;            //当在xml中指定控件的宽高为match_parent或者指定数值的宽高时,回调以下代码            case MeasureSpec.EXACTLY://android:layout_width="match_parent" android:layout_width="40dp"                wSize = hSize = Math.min(wSize, hSize);                break;        }        //只要重写onMeasure()方法,一定要调用以下方法,不然会报错        setMeasuredDimension(wSize, hSize);    }    public void onInfo(){        postInvalidate();        one = 360;        two = 360;        three = 360;        fore =360;    };}

2、MainAcitity主方法

public class MainActivity extends AppCompatActivity {    private ProgressView onPro;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        onPro = (ProgressView) findViewById(R.id.onPro);    }    public void onPlay(View v){        new Thread(){            @Override            public void run() {                super.run();                onPro.onInfo();            }        }.start();    }}
原创粉丝点击