自定义View---实现半圆环形进度条

来源:互联网 发布:vscode c 插件 编辑:程序博客网 时间:2024/06/11 15:44

图表控件很多,这个多少能跟图表控件扯上边吧。
废话不多说,看图:
这里写图片描述

上面可以看到效果,支持各种自定义,支持点击

这里没有用到 自定义属性。有兴趣的可以自己设置下。直接看代码

    public class CircleBar extends View {    private static final String TAG = "CircleBar";    private RectF mColorWheelRectangle = new RectF();//圆圈的矩形范围    private Paint mDefaultWheelPaint;////绘制底部灰色圆圈的画笔    private Paint mColorWheelPaint;//绘制蓝色扇形的画笔    private Paint textPaint;//中间数值文字的画笔    private Paint textDesPaint;//描述文字的画笔    private float mColorWheelRadius;    private float circleStrokeWidth;//圆圈的线条粗细    private float pressExtraStrokeWidth;    private int mTextColor = getResources().getColor(R.color.blue);//默认文字颜色    private int mWheelColor = getResources().getColor(R.color.blue);//默认圆环颜色    private String mText;    private String mTextDes;//文字的描述    private int mTextDesSize;//描述文字的大小    private int mCount;//为了做动画    private float mSweepAnglePer;//扇形弧度百分比    private float mSweepAngle;//扇形弧度    private int mTextSize;//文字大小    private int mDistance;// 上下文字的距离    BarAnimation anim;//动画    private int TIME = 1000;//时间    public CircleBar(Context context) {        super(context);        init(null, 0);    }    public CircleBar(Context context, AttributeSet attrs) {        super(context, attrs);        init(attrs, 0);    }    public CircleBar(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(attrs, defStyle);    }    private void init(AttributeSet attrs, int defStyle) {        //初始化一些值        circleStrokeWidth = dip2px(getContext(), 10);        pressExtraStrokeWidth = dip2px(getContext(), 2);        mTextSize = dip2px(getContext(), 30);        mTextDesSize = dip2px(getContext(), 15);        mDistance = dip2px(getContext(), 30);//文字距离        //外圆环的画笔        mColorWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mColorWheelPaint.setColor(mWheelColor);        mColorWheelPaint.setStyle(Style.STROKE);        mColorWheelPaint.setStrokeWidth(circleStrokeWidth);//圆圈的线条粗细        mColorWheelPaint.setStrokeCap(Paint.Cap.ROUND);//开启显示边缘为圆形        //默认圆的画笔        mDefaultWheelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        mDefaultWheelPaint.setColor(getResources().getColor(R.color.gray));        mDefaultWheelPaint.setStyle(Style.STROKE);        mDefaultWheelPaint.setStrokeWidth(circleStrokeWidth);//圆圈的线条粗细        mDefaultWheelPaint.setStrokeCap(Paint.Cap.ROUND);//开启显示边缘为圆形        //数值的画笔        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);        textPaint.setColor(mTextColor);        textPaint.setStyle(Style.FILL_AND_STROKE);        textPaint.setTextAlign(Align.LEFT);        textPaint.setTextSize(mTextSize);        //描述文字的画笔        textDesPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);        textDesPaint.setColor(getResources().getColor(R.color.gray));        textDesPaint.setStyle(Style.FILL_AND_STROKE);        textDesPaint.setTextSize(mTextDesSize);        textDesPaint.setTextAlign(Align.LEFT);        mText = "0";        mTextDes = "本次考试";        mSweepAngle = 0;        anim = new BarAnimation();        anim.setDuration(TIME);    }    @Override    protected void onDraw(Canvas canvas) {        canvas.drawArc(mColorWheelRectangle, -180, 180, false, mDefaultWheelPaint);//画外接的圆环        canvas.drawArc(mColorWheelRectangle, -180, mSweepAnglePer, false, mColorWheelPaint);//画圆环        Rect bounds = new Rect();        String textstr = mCount + "";        textPaint.getTextBounds(textstr, 0, textstr.length(), bounds);        textDesPaint.getTextBounds(mTextDes, 0, mTextDes.length(), bounds);        // drawText各个属性的意思(文字,x坐标,y坐标,画笔)        canvas.drawText(                textstr + "",                (mColorWheelRectangle.centerX())                        - (textPaint.measureText(textstr) / 2),                mColorWheelRectangle.centerY() + bounds.height() / 2 - 50,                textPaint);        canvas.drawText(mTextDes,                (mColorWheelRectangle.centerX())                        - (textDesPaint.measureText(mTextDes) / 2),                mColorWheelRectangle.centerY() + bounds.height() / 2 - 50 - mDistance                , textDesPaint);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int height = getDefaultSize(getSuggestedMinimumHeight(),                heightMeasureSpec);        int width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        int min = Math.min(width, height);        setMeasuredDimension(min, min);        mColorWheelRadius = min - circleStrokeWidth - pressExtraStrokeWidth;        mColorWheelRectangle.set(circleStrokeWidth + pressExtraStrokeWidth, circleStrokeWidth + pressExtraStrokeWidth,                mColorWheelRadius, mColorWheelRadius);    }    @Override    public void setPressed(boolean pressed) {        Toast.makeText(getContext(), mText, Toast.LENGTH_SHORT).show();    }    public void startCustomAnimation() {        this.startAnimation(anim);    }    public void setText(String text) {        mText = text;        this.startAnimation(anim);    }    public void setDesText(String text) {        mTextDes = text;        this.startAnimation(anim);    }    public void setTextColor(int color) {        mTextColor = color;        textPaint.setColor(mTextColor);    }    public void setSweepAngle(float sweepAngle) {        mSweepAngle = sweepAngle;    }    public void setWheelColor(int color) {        this.mColorWheelPaint.setColor(color);    }    public class BarAnimation extends Animation {        /**         * Initializes expand collapse animation, has two types, collapse (1) and expand (0).         * 1 will collapse view and set to gone         */        public BarAnimation() {        }        //        * 动画类利用了applyTransformation参数中的interpolatedTime参数(从0到1)的变化特点,//                * 实现了该View的某个属性随时间改变而改变。原理是在每次系统调用animation的applyTransformation()方法时,//                * 改变mSweepAnglePer,mCount的值,//                * 然后调用postInvalidate()不停的绘制view。        @Override        protected void applyTransformation(float interpolatedTime, Transformation t) {            super.applyTransformation(interpolatedTime, t);            //mSweepAnglePer,mCount这两个属性只是动画过程中要用到的临时属性,            //mText和mSweepAngle才是动画结束之后表示扇形弧度和中间数值的真实值。            if (interpolatedTime < 1.0f) {                mSweepAnglePer = interpolatedTime * mSweepAngle;                mCount = (int) (interpolatedTime * Float.parseFloat(mText));            } else {                mSweepAnglePer = mSweepAngle;                mCount = Integer.parseInt(mText);            }            postInvalidate();        }    }    public static int dip2px(Context context, float dipValue) {        final float scale = context.getResources().getDisplayMetrics().density;        return (int) (dipValue * scale + 0.5f);    }}

注释非常清楚了。就不详细说明了。直接在在布局中使用。因为没有自定义属性,大家懂的。

源码地址飞机票

这里添加点击事件,通常继承自view都有onClick和oLongClick事件的。这里加进去就好

    //监听器类接口    public static abstract interface  OnClickListener{        public abstract void onClick(); //单击事件处理接口    }    OnClickListener   listener=null;   //监听器类对象    //实现这个View的监听器    public void setOnClickListener(OnClickListener  listener){        this.listener = listener;   //引用监听器类对象,在这里可以使用监听器类的对象    }
0 0
原创粉丝点击