Android 仪表盘组件范例,需要稍加修改即可。

2019PHP高薪工程师学习路线图....>>>

支持android 2.2以上平台。注:
代码中有用到一个工具类的dpToPx的方法,用来转换dp单位值到px的,暂时没有提供,朋友们可以自行编写然后对代码进行替换。

在activity中使用,下面是范例代码,   至于怎么正确放置代码,相信做过android的朋友都很熟悉了。

           FinanceScoreDialView fcdView =new  FinanceScoreDialView(context);
           addview(fcdView);

            fcdView.setValues(new double[]{80.5, 10});
            fcdView.setScoreTitleString("第三季度");
            fcdView.setRankingTitleString("行业排名");
            fcdView.setScoreTitleColor(0xff666666);
            fcdView.setScoreColor(0xffc1611e);
            fcdView.setRankingTitleColor(0xff666666);
            fcdView.setRankingColor(Color.WHITE);

            fcdView.setInnerScoreRingColor(0xffc1ddf9);
            fcdView.setOuterScoreRingColor(0xff328deb);
            fcdView.setOuterScoreSelRingColor(0xffc1611e);
            fcdView.setScoreAxisLineColor(0xff00ff00);
            fcdView.setScoreAxisLables(5);

            fcdView.postInvalidate();
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;

import java.text.NumberFormat;


class FinanceScoreDialView extends  View{

    private double score;   //

    private int ranking;

    private String mScoreTitleStr;     //表盘标题
    private String mRankingTitleStr;   
    private int mScoreAxisLineColor;   //表盘刻度文字

    public void setScoreTitleColor(int mScoreTitleColor) {
        this.mScoreTitleColor = mScoreTitleColor;
    }

    public void setScoreColor(int mScoreColor) {
        this.mScoreColor = mScoreColor;
    }

    public void setRankingTitleColor(int mRankingTitleColor) {
        this.mRankingTitleColor = mRankingTitleColor;
    }

    public void setRankingColor(int mRankingColor) {
        this.mRankingColor = mRankingColor;
    }

    private int mScoreTitleColor;  //表盘标题文字颜色
    private int mScoreColor;      
    private int mRankingTitleColor;
    private int mRankingColor;

    public void setInnerScoreRingColor(int mInnerScoreRingColor) {
        this.mInnerScoreRingColor = mInnerScoreRingColor;
    }

    public void setOuterScoreRingColor(int mOuterScoreRingColor) {
        this.mOuterScoreRingColor = mOuterScoreRingColor;
    }

    public void setOuterScoreSelRingColor(int mOuterScoreSelRingColor) {
        this.mOuterScoreSelRingColor = mOuterScoreSelRingColor;
    }

    public void setScoreAxisLineColor(int axisLineColor){
        this.mScoreAxisLineColor = axisLineColor;
    }

    private int mInnerScoreRingColor;
    private int mOuterScoreRingColor;
    private int mOuterScoreSelRingColor;

    private float totalScore = 100;

    private float stepDegree = -1;

    public void setScoreAxisLables(int scoreAxisLables) {
        this.scoreAxisLables = scoreAxisLables;

        axisLabelStrs = new String[scoreAxisLables];

        float step = totalScore / (scoreAxisLables-1);

        for (int i =0; i< scoreAxisLables; i++){
            axisLabelStrs[i] = String.valueOf(nFormat2.format(step *i));
        }

        float sweepAngle = 180+Math.abs(2*offset_degree);

        stepDegree = sweepAngle/(scoreAxisLables-1);


    }

    private int scoreAxisLables;
    private String[] axisLabelStrs;

    private float axisLineWidth = Tool.dpToPx(0.5f);


    private float axisLableTextSize = Tool.dpToPx(12);

    private Paint axisLablePaint = new Paint();


    private float leftmargin = Tool.dpToPx(5);

    private float v_margin = Tool.dpToPx(15);

    private float h_space  = Tool.dpToPx(15);

    private float ring_space = Tool.dpToPx(5);

    private float outter_ringWidth = Tool.dpToPx(1);

    private float inner_ringWidth = Tool.dpToPx(5);


    private Paint rankingTextPaint = new Paint();
    private Paint scoreTextPaint = new Paint();

    private Paint scoreRingPaint = new Paint();

    private float scoreTitleTextSize = Tool.dpToPx(14);
    private float rankingTitleTextSize = Tool.dpToPx(14);
    private float scoreTextSize  = Tool.dpToPx(40);
    private float rankingTextSize  = Tool.dpToPx(30);

    private static final float offset_degree = -10;  //负代表往下偏移10度


    private float maxOutterScoreDiameter = -1;

    private float maxOutterScoreRadius = -1;

    private float innerScoreDiameter = -1;

    private RectF ring_rectf = new RectF();

    private static NumberFormat nFormat = NumberFormat.getNumberInstance();
    private static NumberFormat nFormat2 = NumberFormat.getNumberInstance();

    static{
        nFormat.setMaximumFractionDigits(2);
        nFormat.setMinimumFractionDigits(2);

        nFormat2.setMaximumFractionDigits(0);
    }



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

    private void init(){
        rankingTextPaint.setAntiAlias(true);
        scoreTextPaint.setAntiAlias(true);
        scoreRingPaint.setAntiAlias(true);
    }

    public void setValues(double[] values){
        if(null != values){
            if(values.length >0){
                score = values[0];
            }

            if(values.length >1 ){
                ranking = (int)values[1];
            }
        }
    }

    public void setScoreTitleString(String str){
        this.mScoreTitleStr = str;

    }

    public void setRankingTitleString(String str){
        this.mRankingTitleStr = str;
    }

    public  void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        int specWidth = MeasureSpec.getSize(widthMeasureSpec);
        int measuredWidth = specWidth;

        int measuredHeight = 0;

        scoreTextPaint.setTextSize(scoreTitleTextSize);
        float scoretitle_h  = getFontHeight(scoreTextPaint);
        float scoretitle_w = scoreTextPaint.measureText(mScoreTitleStr);

        scoreTextPaint.setTextSize(scoreTextSize);
        float score_h  = getFontHeight(scoreTextPaint);
        float score_w = scoreTextPaint.measureText(nFormat.format(score));


        float totalh_score = scoretitle_h + Tool.dpToPx(5) + score_h;
        float totalw_score = Math.max(scoretitle_w,score_w) + 2*Tool.dpToPx(20);

        float score_diameter = Math.max(totalw_score, totalh_score);

        float max_outter_score_diameter = score_diameter + 2* (inner_ringWidth + ring_space + outter_ringWidth);

        maxOutterScoreDiameter = max_outter_score_diameter;

        innerScoreDiameter = max_outter_score_diameter - 2*(outter_ringWidth + ring_space);

        float max_outter_score_radius = max_outter_score_diameter/2;
        maxOutterScoreRadius = max_outter_score_radius;
        measuredHeight += max_outter_score_radius;

        double rAngle = Math.toRadians(90 - (-180 + offset_degree));

        measuredHeight += Math.abs(max_outter_score_radius*Math.cos(rAngle));
        measuredHeight += 2*v_margin;


        setMeasuredDimension(measuredWidth, measuredHeight);


    }

    public void onDraw(Canvas canvas){

        int startX = getScrollX();
        int startY = getScrollY();

        rankingTextPaint.setTextSize(rankingTitleTextSize);
        rankingTextPaint.setColor(mRankingTitleColor);

        float rankingTitleBaseline = startY + v_margin + getFontTopYToBaseline(rankingTextPaint);
        canvas.drawText(mRankingTitleStr, startX + leftmargin, rankingTitleBaseline, rankingTextPaint);


        float rankingTitle_w = rankingTextPaint.measureText(mRankingTitleStr);

        //圆心纵横坐标
        float centerX  = startX + leftmargin + h_space + rankingTitle_w + maxOutterScoreDiameter/2;
        float centerY =startY + v_margin + maxOutterScoreDiameter/2;


        float max_outter_ring_startX = centerX - maxOutterScoreDiameter/2 + outter_ringWidth/2;
        float max_outter_ring_startY = v_margin + outter_ringWidth/2;
        float max_outter_ring_endX = max_outter_ring_startX + maxOutterScoreDiameter - outter_ringWidth;
        float max_outter_ring_endY = max_outter_ring_startY + maxOutterScoreDiameter - outter_ringWidth;

        ring_rectf.set(max_outter_ring_startX, max_outter_ring_startY, max_outter_ring_endX, max_outter_ring_endY);

        scoreRingPaint.setStyle(Paint.Style.STROKE);
        scoreRingPaint.setStrokeWidth(outter_ringWidth);

        scoreRingPaint.setColor(mOuterScoreRingColor);

        float startAngle = -180 + offset_degree;
        float sweepAngle = 180+Math.abs(2*offset_degree);

        float sweepAngle1 = (float)(sweepAngle * score/ totalScore);

        if(sweepAngle1 > sweepAngle || (sweepAngle-sweepAngle1<1)){
            sweepAngle1 = sweepAngle;
        }



        canvas.drawArc(ring_rectf,startAngle,sweepAngle,false,scoreRingPaint );    //画外环

        scoreRingPaint.setColor(mOuterScoreSelRingColor);
        canvas.drawArc(ring_rectf,startAngle,sweepAngle1,false,scoreRingPaint );

        float inner_ring_startX = centerX - innerScoreDiameter/2 + inner_ringWidth/2;
        float inner_ring_startY = centerY - innerScoreDiameter/2 + inner_ringWidth/2;
        float inner_ring_endX = inner_ring_startX + innerScoreDiameter - inner_ringWidth;
        float inner_ring_endY = inner_ring_startY + innerScoreDiameter - inner_ringWidth;

        ring_rectf.set(inner_ring_startX, inner_ring_startY, inner_ring_endX, inner_ring_endY);

        scoreRingPaint.setStrokeWidth(inner_ringWidth);
        scoreRingPaint.setColor(mInnerScoreRingColor);
        canvas.drawArc(ring_rectf, startAngle, sweepAngle, false, scoreRingPaint);

        for (int i =0; i<scoreAxisLables; i++){
            float degree = -1;

            degree =  -180 + offset_degree + stepDegree * i;

            double radian = Math.toRadians(90-degree);

            float shortRadius = innerScoreDiameter/2 - inner_ringWidth;
            float longRadius = innerScoreDiameter/2;

            double sinValue = Math.sin(radian);
                    double cosValue = Math.cos(radian);

            float x1 =  (float) (centerX +shortRadius * sinValue);
            float y1 = (float)(centerY +shortRadius * cosValue);
            float x2 = (float)(centerX +  longRadius * sinValue);
            float y2 = (float)(centerY + longRadius * cosValue);

            scoreRingPaint.setStyle(Paint.Style.STROKE);
            scoreRingPaint.setStrokeWidth(axisLineWidth);
            scoreRingPaint.setColor(mScoreAxisLineColor);



            canvas.drawLine(x1, y1, x2, y2, scoreRingPaint);


            axisLablePaint.setTextSize(axisLableTextSize);
            axisLablePaint.setTextAlign(Paint.Align.CENTER);
            axisLablePaint.setColor(mInnerScoreRingColor);

            float axisLable_fonth = getFontHeight(axisLablePaint);
            float labelRadius =innerScoreDiameter/2 - inner_ringWidth - axisLable_fonth/2 + 3;

            float x3 =  (float) (centerX + labelRadius * sinValue);
                    float y3  =(float) (centerY + labelRadius * cosValue);

            canvas.save();

            canvas.rotate(90+ degree,x3,y3);    //绘制倾斜文字


            canvas.drawText(axisLabelStrs[i],x3,y3 + getFontCenterYToBaseLine(axisLablePaint),axisLablePaint);

            canvas.restore();

        }


        scoreTextPaint.setTextAlign(Paint.Align.CENTER);
        scoreTextPaint.setTextSize(scoreTextSize);
        scoreTextPaint.setColor(mScoreColor);

        double rAngle = Math.toRadians(90 - (-180 + offset_degree));    //弧度

        float offset_y = (float)(maxOutterScoreRadius*Math.cos(rAngle));

        float scoreBaselineY = centerY + offset_y;
        float tempH = getFontTopYToBaseline(scoreTextPaint);

        canvas.drawText(nFormat.format(score), centerX, scoreBaselineY, scoreTextPaint);

        scoreTextPaint.setTextSize(scoreTitleTextSize);
        scoreTextPaint.setColor(mScoreTitleColor);

        float scoreTitleBaselineY = scoreBaselineY - tempH - Tool.dpToPx(2);

        canvas.drawText(mScoreTitleStr, centerX, scoreTitleBaselineY, scoreTextPaint);


    }


    public static float getFontHeight(Paint textPaint){

        Paint.FontMetrics fm = textPaint.getFontMetrics();

        return (float)Math.ceil(fm.descent - fm.ascent) + 3;
    }


    public static float getFontTopYToBaseline(Paint textPaint){
        Paint.FontMetrics fm = textPaint.getFontMetrics();

        return (float)Math.ceil(-fm.ascent) + 3;
    }

    public static float getFontBottomYToBaseline(Paint textPaint){
        Paint.FontMetrics fm = textPaint.getFontMetrics();

        return (float)Math.ceil(fm.descent) + 3;
    }

    public static float getFontCenterYToBaseLine(Paint textPaint){
        Paint.FontMetrics fm = textPaint.getFontMetrics();

        float fonth = getFontHeight(textPaint);

        return (float)Math.abs(Math.ceil(fonth/2- fm.descent));
    }

}