"圆形统计图"DEMO

话不多说先上图吐舌头


自定义圆形分布统计图:RingView
public class RingView extends View {

    private Context mContext;
    private Paint mPaint;
    private int mPaintWidth = 0;        // 画笔的宽
    private int topMargin = 0;         // 上边距30
    private int leftMargin = 0;        // 左边距 80
    private Resources mRes;
    private DisplayMetrics dm;
    private int showRateSize = 10; // 展示文字的大小

    private int MaxRidus = 44;
    private int Ridus = MaxRidus;
    /*默认MaxRidus为外圆半径,内圆占其1/2,点所在圆的半径占5/6     */
    private int circleCenterX = Ridus;     // 圆心点X  要与外圆半径相等96
    private int circleCenterY = Ridus;     // 圆心点Y  要与外圆半径相等96

    private int ringOuterRidus = Ridus;     // 外圆的半径96
    private int ringInnerRidus = Ridus * 1 / 2;     // 内圆的半径33
    private int ringPointRidus = Ridus * 5 / 6;    // 点所在圆的半径80

    private float rate = 0.1f;     //点的外延距离  与  点所在圆半径的长度比率
    private float extendLineWidth = 1;     //点外延后  折的横线的长度 20

    private RectF rectF;                // 外圆所在的矩形
    private RectF rectFPoint;           // 点所在的矩形

    private List<Integer> colorList;
    private List<Float> rateList;
    private boolean isRing;
    private boolean isShowCenterPoint;
    private boolean isShowRate;

    public RingView(Context context) {
        super(context, null);
    }

    public RingView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
//        initView();
    }


    public void setShow(List<Integer> colorList, List<Float> rateList) {
        setShow(colorList, rateList, 44);
    }

    public void setShow(List<Integer> colorList, List<Float> rateList, int Ridus) {
        setShow(colorList, rateList, Ridus, true);
    }

    public void setShow(List<Integer> colorList, List<Float> rateList, int Ridus, boolean isShowRate) {
        setShow(colorList, rateList, Ridus, isShowRate, false);
    }

    public void setShow(List<Integer> colorList, List<Float> rateList, int Ridus, boolean isShowRate, boolean isRing) {
        setShow(colorList, rateList, isShowRate, isRing, false, Ridus);
    }

    /*画图的方向从右向左顺时针旋转*/
    //    isRing:是否画内圆     isShowRate:是否显示比例占比的线和点      isShowCenterPoint:是否画圆心  Ridus:自定义半径
    public void setShow(List<Integer> colorList, List<Float> rateList, boolean isShowRate,
                        boolean isRing, boolean isShowCenterPoint, int Ridus) {
        this.colorList = colorList;
        this.rateList = rateList;
        this.isRing = isRing;
        this.isShowRate = isShowRate;
        this.isShowCenterPoint = isShowCenterPoint;
        this.Ridus = Ridus;
    }

    private void initView() {
        this.mRes = mContext.getResources();
        this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
        int screenWidth = wm.getDefaultDisplay().getWidth();
//        int height = wm.getDefaultDisplay().getHeight();
        leftMargin = (px2dip(screenWidth) - (2 * circleCenterX)) / 2;

        mPaint.setColor(ContextCompat.getColor(mContext, R.color.red));
        mPaint.setStrokeWidth(dip2px(mPaintWidth));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        rectF = new RectF(dip2px(mPaintWidth + leftMargin),
                dip2px(mPaintWidth + topMargin),
                dip2px(circleCenterX + ringOuterRidus + mPaintWidth * 2 + leftMargin),
                dip2px(circleCenterY + ringOuterRidus + mPaintWidth * 2 + topMargin));

        rectFPoint = new RectF(dip2px(mPaintWidth + leftMargin + (ringOuterRidus - ringPointRidus)),
                dip2px(mPaintWidth + topMargin + (ringOuterRidus - ringPointRidus)),
                dip2px(circleCenterX + ringPointRidus + mPaintWidth * 2 + leftMargin),
                dip2px(circleCenterY + ringPointRidus + mPaintWidth * 2 + topMargin));

        Log.e("矩形点:", dip2px(circleCenterX + ringOuterRidus + mPaintWidth * 2) + " --- " + dip2px(circleCenterY + ringOuterRidus + mPaintWidth * 2));

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        pointList.clear();

        /*自定义初始化圆的半径*/
        if (Ridus != MaxRidus) {
            circleCenterX = Ridus;
            circleCenterY = Ridus;
            ringOuterRidus = Ridus;
            ringInnerRidus = Ridus * 1 / 2;
            ringPointRidus = Ridus * 5 / 6;
        }

        initView();

        if (colorList != null) {
            for (int i = 0; i < colorList.size(); i++) {
                mPaint.setColor(mRes.getColor(colorList.get(i)));
                mPaint.setStyle(Paint.Style.FILL);
                drawOuter(canvas, i);
            }
        }
        mPaint.setStyle(Paint.Style.FILL);
        if (isRing) {
            drawInner(canvas);
        }
        if (isShowCenterPoint) {
            drawCenterPoint(canvas);
        }

    }

    /*画圆的中心点*/
    private void drawCenterPoint(Canvas canvas) {
        mPaint.setColor(ContextCompat.getColor(mContext, R.color.red));
//        Log.e("中心点:", dip2px(circleCenterX + mPaintWidth * 2 + leftMargin) + " --- " + dip2px(circleCenterY + mPaintWidth * 2 + topMargin));
        canvas.drawCircle(dip2px(circleCenterX + mPaintWidth * 2 + leftMargin), dip2px(circleCenterY + mPaintWidth * 2 + topMargin), dip2px(1), mPaint);
    }

    /*画内圆*/
    private void drawInner(Canvas canvas) {
        mPaint.setColor(ContextCompat.getColor(mContext, R.color.white));
//        Log.e("内部圆点:", dip2px(circleCenterX + mPaintWidth * 2 + leftMargin) + " --- " + dip2px(circleCenterY + mPaintWidth * 2 + topMargin));
        canvas.drawCircle(dip2px(circleCenterX + mPaintWidth * 2 + leftMargin), dip2px(circleCenterY + mPaintWidth * 2 + topMargin), dip2px(ringInnerRidus), mPaint);
    }

    private float preRate;

    private void drawArcCenterPoint(Canvas canvas, int position) {
        mPaint.setStyle(Paint.Style.STROKE);
// 显示比例占比的外部轮廓颜色尽量选透明transparent不然好丑
        mPaint.setColor(ContextCompat.getColor(mContext, R.color.transparent));
        mPaint.setStrokeWidth(dip2px(1));
        canvas.drawArc(rectFPoint, preAngle, (endAngle) / 2, true, mPaint);
        dealPoint(rectFPoint, preAngle, (endAngle) / 2, pointArcCenterList);
        Point point = pointArcCenterList.get(position);
//       显示比例占比的圆点的颜色
        mPaint.setColor(ContextCompat.getColor(mContext, R.color.gold));
        canvas.drawCircle(point.x, point.y, dip2px(2), mPaint);

        if (preRate / 2 + rateList.get(position) / 2 < 5) {
            extendLineWidth += 20;
            rate -= 0.05f;
        } else {
            extendLineWidth = 20;
            rate = 0.4f;
        }

        // 外延画折线
        float lineXPoint1 = (point.x - dip2px(leftMargin + ringOuterRidus)) * (1 + rate);
        float lineYPoint1 = (point.y - dip2px(topMargin + ringOuterRidus)) * (1 + rate);

        float[] floats = new float[8];
        floats[0] = point.x;
        floats[1] = point.y;
        floats[2] = dip2px(leftMargin + ringOuterRidus) + lineXPoint1;
        floats[3] = dip2px(topMargin + ringOuterRidus) + lineYPoint1;
        floats[4] = dip2px(leftMargin + ringOuterRidus) + lineXPoint1;
        floats[5] = dip2px(topMargin + ringOuterRidus) + lineYPoint1;
        if (point.x >= dip2px(leftMargin + ringOuterRidus)) {
            mPaint.setTextAlign(Paint.Align.LEFT);
            floats[6] = dip2px(leftMargin + ringOuterRidus) + lineXPoint1 + dip2px(extendLineWidth);
        } else {
            mPaint.setTextAlign(Paint.Align.RIGHT);
            floats[6] = dip2px(leftMargin + ringOuterRidus) + lineXPoint1 - dip2px(extendLineWidth);
        }
        floats[7] = dip2px(topMargin + ringOuterRidus) + lineYPoint1;
        mPaint.setColor(mRes.getColor(colorList.get(position)));
        canvas.drawLines(floats, mPaint);
        mPaint.setTextSize(dip2px(showRateSize));
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawText(rateList.get(position) + "%", floats[6], floats[7] + dip2px(showRateSize) / 3, mPaint);
        preRate = rateList.get(position);
    }

    List<Point> pointList = new ArrayList<>();
    List<Point> pointArcCenterList = new ArrayList<>();

    private void dealPoint(RectF rectF, float startAngle, float endAngle, List<Point> pointList) {
        Path orbit = new Path();
        //通过Path类画一个90度(180—270)的内切圆弧路径
        orbit.addArc(rectF, startAngle, endAngle);

        PathMeasure measure = new PathMeasure(orbit, false);
        Log.e("路径的测量长度:", "" + measure.getLength());

        float[] coords = new float[]{0f, 0f};
        //利用PathMeasure分别测量出各个点的坐标值coords
        int divisor = 1;
        measure.getPosTan(measure.getLength() / divisor, coords, null);
        Log.e("coords:", "x轴:" + coords[0] + " -- y轴:" + coords[1]);
        float x = coords[0];
        float y = coords[1];
        Point point = new Point(Math.round(x), Math.round(y));
        pointList.add(point);
    }

    private void drawOuter(Canvas canvas, int position) {
//        canvas.drawCircle(circleCenterX, circleCenterY, ringInnerRidus, mPaint);
        if (rateList != null) {
            endAngle = getAngle(rateList.get(position));
        }
//        Log.e("preAngle:", "" + preAngle + "   endAngle:" + endAngle);
        canvas.drawArc(rectF, preAngle, endAngle, true, mPaint);
//        dealPoint(rectF, preAngle, endAngle, pointList);

        if (isShowRate) {
            drawArcCenterPoint(canvas, position);
        }

        preAngle = preAngle + endAngle;
    }

    private float preAngle = -90;
    private float endAngle = -90;

    /**
     * @param percent 百分比
     * @return
     */
    private float getAngle(float percent) {
        float a = 360f / 100f * percent;
        return a;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int dip2px(float dpValue) {
        return (int) (dpValue * dm.density + 0.5f);
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int px2dip(float pxValue) {
        return (int) (pxValue / dm.density + 0.5f);
    }

}


划重点


 /*画图的方向从右向左顺时针旋转 colorList传进来得颜色集合  rateList所占的比例集合(切记和要为100)*/
    //    isRing:是否画内圆     isShowRate:是否显示比例占比的线和点      isShowCenterPoint:是否画圆心  Ridus:自定义半径
    public void setShow(List<Integer> colorList, List<Float> rateList, boolean isShowRate,
                        boolean isRing, boolean isShowCenterPoint, int Ridus) {
        this.colorList = colorList;
        this.rateList = rateList;
        this.isRing = isRing;
        this.isShowRate = isShowRate;
        this.isShowCenterPoint = isShowCenterPoint;
        this.Ridus = Ridus;
    }


调用:

 private RingView devRing, declareRing;
    private TextView devsum, declareSum, declareDeal, declareUndeal;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        baseapp.addActivity(this);
        initView();
        setData();
    }


    private void initView() {
        findViewById(R.id.mainUser).setOnClickListener(this);
        findViewById(R.id.mainNotification).setOnClickListener(this);
        devRing = (RingView) findViewById(R.id.main_ringdev);
        declareRing = (RingView) findViewById(R.id.main_ringdeclare);
        declareSum = (TextView) findViewById(R.id.main_declaresum);
        declareSum.setText("11");
        declareDeal = (TextView) findViewById(R.id.declare_deal);
        declareUndeal = (TextView) findViewById(R.id.declare_undeal);

        devsum = (TextView) findViewById(R.id.main_devsum);


    }


    /*初始化统计图的数据*/
    private void setData() {
        int a = new Random().nextInt(11);
        int b = 11 - a;
        float aa = (float) (a * 1.0 / 11 * 100);
        float bb = (float) (b * 1.0 / 11 * 100);
        declareUndeal.setText("" + b);
        declareDeal.setText(String.valueOf(a));
        List<Float> rateDeclare = new ArrayList<>();
        rateDeclare.add(Float.parseFloat(new DecimalFormat(".##").format(bb)));
        rateDeclare.add(Float.parseFloat(new DecimalFormat(".##").format(aa)));

        List colorDeclare = new ArrayList<>();
        colorDeclare.add(R.color.red_deep);
        colorDeclare.add(R.color.green);

        declareRing.setShow(colorDeclare, rateDeclare);

        // 添加的是颜色
        List colorList = new ArrayList<>();
        colorList.add(R.color.red_deep);
        colorList.add(R.color.orange_deep);
        colorList.add(R.color.green);

        //  添加的是百分比
        List<Float> rateList = new ArrayList<>();
        rateList.add(50.7f);
        rateList.add(5.3f);
        rateList.add(44f);
        devRing.setShow(colorList, rateList);
    }



布局:

 <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">


            <TextView
                android:id="@+id/declare_deal_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="@dimen/main_margin"
                android:text="已处理:"
                android:textColor="@color/black"
                android:textSize="@dimen/main_tv" />

            <TextView
                android:id="@+id/declare_deal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBottom="@id/declare_deal_tv"
                android:layout_toRightOf="@id/declare_deal_tv"
                android:text="XX"
                android:textColor="@color/green"
                android:textSize="@dimen/main_tv" />

            <TextView
                android:id="@+id/declare_undeal"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="@dimen/main_margin"
                android:text="XX"
                android:textColor="@color/red_deep"
                android:textSize="@dimen/main_tv" />

            <TextView
                android:id="@+id/declare_undeal_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@id/declare_undeal"
                android:text="未处理:"
                android:textColor="@color/black"
                android:textSize="@dimen/main_tv" />

            <com.bs.afterservice.view.RingView
                android:id="@+id/main_ringdeclare"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true" />

        </RelativeLayout>











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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值