自定义控件-半扇形空心统计图

效果图

 

直接上代码,具体看注释

public class MyChart extends View {

    final String TAG = "xzc";

    public MyChart(Context context) {
        this(context,null);

    }

    public MyChart(Context context, @Nullable AttributeSet attrs) {
        this(context,attrs,0);
    }

    public MyChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context,attrs,defStyleAttr,0);
    }

    public MyChart(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context,attrs,defStyleAttr,defStyleRes);

        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.module_user_myChart);

        mName = array.getString(R.styleable.module_user_myChart_module_user_name);
        mCountColor = array.getColor(R.styleable.module_user_myChart_module_user_countColor,Color.BLACK);
        mTextColor = array.getColor(R.styleable.module_user_myChart_module_user_textColor,Color.BLACK);
        mCurColor = array.getColor(R.styleable.module_user_myChart_module_user_curColor,0xFF19CAAD);
        mBackgroundColor = array.getColor(R.styleable.module_user_myChart_module_user_backgroundColor,0x37000000);
        array.recycle();

        init();

    }

    private int mMin = 0;
    private int mCur = 50;
    private int mMax = 100;
    private int mPer = 25;

    private int mCountColor = Color.BLACK;     // 当前进度数量值
    private int mTextColor = Color.BLACK;      // 文字
    private int mCurColor = Color.YELLOW;     // 当前进度图案
    private int mBackgroundColor = Color.GRAY;          // 图表背景

    private Paint mPaint;
    private Path mBackgroundArcPath;
    private Path mCurrArcPath;
    private Path mCirclePath;

    private int mScaleCount = 8;

    private RectF mBackgroundArRect;

    private PointF mCenter;
    private float mRadius;
    private int mTextSize;         // 文字字体大小
    private int mScaleTextSize;    // 刻度字体大小

    private int mTextSizeDefault = 10;         // 默认文字字体大小   dp
    private int mScaleTextSizeDefault = 8;    // 默认刻度字体大小    dp

    private String mName = "";
    private String mCurString = "0";

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);


        mBackgroundArcPath = new Path();
        mCurrArcPath = new Path();
        mCirclePath = new Path();

        mBackgroundArRect = new RectF();
        mCenter = new PointF();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        setMeasuredDimension(widthMeasureSpec, widthMeasureSpec);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mCenter.x = w/2+getPaddingLeft();
        mCenter.y = h / 4 * 3+getPaddingTop();
        mRadius = w/4;
        mBackgroundArRect.set(0, h / 4, w, (int) (h / 4 * 3 + h / 2));

        mTextSize = (int) (dpToPx(mTextSizeDefault)*w/360f);
        mScaleTextSize = (int) (dpToPx(mScaleTextSizeDefault)*w/360f);
        Log.i(TAG,"w= "+w+",h = "+h);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mBackgroundArcPath.reset();
        mCirclePath.reset();
        //mPaint.reset();

        mBackgroundArcPath.setFillType(Path.FillType.WINDING);

        // 绘制背景
        mBackgroundArcPath.addArc(mBackgroundArRect,-135,89);
        mBackgroundArcPath.lineTo(mCenter.x,mCenter.y);
        //mBackgroundArcPath.close();


        mCirclePath.addCircle(mCenter.x, mCenter.y, (float) (mRadius*1.2), Path.Direction.CW);


        float tmpX;
        float tmpY;
        String tempS;
        Rect bounds = new Rect(); // 矩形对象
        mPaint.setColor(mBackgroundColor);
        mPaint.setTextSize(mScaleTextSize);
        // 绘制刻度
        for(int i=0;i <= mScaleCount;i++){
            // 参数为 弧度,
            tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.2));
            tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.2));
            mBackgroundArcPath.lineTo(tmpX,tmpY);

            tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i+1))*(mRadius*2.2));
            tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i+1))*(mRadius*2.2));

            mBackgroundArcPath.lineTo(tmpX,tmpY);
            mBackgroundArcPath.lineTo(mCenter.x,mCenter.y);

            tmpX = (float) (mCenter.x + Math.cos(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.3));
            tmpY = (float) (mCenter.y + Math.sin(2*Math.PI/360*(-135+90/mScaleCount*i))*(mRadius*2.3));

            tempS = (mMin+mPer*i) +"";
            mPaint.getTextBounds(tempS, 0, tempS.length(), bounds);
            canvas.drawText(tempS,tmpX-bounds.width()/2, tmpY,mPaint);
        }
        //mBackgroundArcPath.close();

        mBackgroundArcPath.op(mCirclePath, Path.Op.DIFFERENCE);
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        canvas.drawPath(mBackgroundArcPath, mPaint);


        //绘制进度
        mBackgroundArcPath.reset();
        mBackgroundArcPath.addArc(mBackgroundArRect,-135,90*mCur/(mMax-mMin));
        mBackgroundArcPath.lineTo(getWidth()/2,getHeight()/4*3);
        mBackgroundArcPath.close();

        mBackgroundArcPath.op(mCirclePath, Path.Op.DIFFERENCE);
        mPaint.setColor(mCurColor);
        canvas.drawPath(mBackgroundArcPath, mPaint);




        mPaint.getTextBounds(mName, 0, mName.length(), bounds);

        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        canvas.drawText(mName,mCenter.x-bounds.width()/2, (float) (mCenter.y-mRadius*0.7),mPaint);

        mPaint.setColor(mCountColor);
        mCurString = mCur+"";
        mPaint.getTextBounds(mCurString, 0, mCurString.length(), bounds);
        canvas.drawText(mCurString,mCenter.x-bounds.width()/2, (float) (mCenter.y-mRadius*0.4),mPaint);
        
    }


    public int dpToPx(int dp) {
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int px = Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return px;
    }

    public int pxToDp(int px) {
        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
        int dp = Math.round(px / (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
        return dp;
    }


    public int getMin() {
        return mMin;
    }

    public void setMin(int mMin) {
        this.mMin = mMin;
        mPer = (mMax-mMin)/mScaleCount;
    }

    public int getCur() {
        return mCur;
    }

    public void setCur(int mCur) {
        this.mCur = mCur;
        postInvalidate();
    }

    public int getMax() {
        return mMax;
    }

    public void setMax(int mMax) {
        this.mMax = mMax;
        mPer = (mMax-mMin)/mScaleCount;
    }



    public int getCountColor() {
        return mCountColor;
    }

    public void setCountColor(int mCountColor) {
        this.mCountColor = mCountColor;
    }

    public int getTextColor() {
        return mTextColor;
    }

    public void setTextColor(int mTextColor) {
        this.mTextColor = mTextColor;
    }

    public int getChartColor() {
        return mCurColor;
    }

    public void setChartColor(int mChartColor) {
        this.mCurColor = mChartColor;
    }

    public int getBackgroundColor() {
        return mBackgroundColor;
    }

    public void setBackgroundColor(int mBackgroundColor) {
        this.mBackgroundColor = mBackgroundColor;
    }


    public int getScaleCount() {
        return mScaleCount;
    }

    public void setScaleCount(int mScaleCount) {
        this.mScaleCount = mScaleCount;
        mPer = (mMax-mMin)/mScaleCount;
    }

    public int getTextSize() {
        return mTextSize;
    }

    public void setTextSize(int mTextSize) {
        this.mTextSize = mTextSize;
    }

    public int getScaleTextSize() {
        return mScaleTextSize;
    }

    public void setScaleTextSize(int mScaleTextSize) {
        this.mScaleTextSize = mScaleTextSize;
    }

    public String getName() {
        return mName;
    }

    public void setName(String mName) {
        this.mName = mName;
    }

}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值