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

下面是编程之家 jb51.cc 通过网络收集整理的代码片段。

编程之家小编现在分享给大家,也给大家做个参考。

支持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,sweepAngle1,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,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],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,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));
    }

}

以上是编程之家(jb51.cc)为你收集整理的全部代码内容,希望文章能够帮你解决所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 连接 连接池产生原因 连接池实现原理 小结 TEMPERANCE:Eat not to dullness;drink not to elevation.节制
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 一个优秀的工程师和一个普通的工程师的区别,不是满天飞的架构图,他的功底体现在所写的每一行代码上。-- 毕玄 1. 命名风格 【书摘】类名用 UpperCamelC
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个人在用”。哪怕只是throw了一个新的Exception。哈哈,这是我犯的错误。一、接口和抽象类类,即一个对象。先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类)。官方定义让人费解,但是记忆方法是也不错的 —包含抽象方法的类叫做抽象类。接口
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket一、引子文件,作为常见的数据源。关于操作文件的字节流就是 —FileInputStream&amp;FileOutputStream。
作者:泥沙砖瓦浆木匠网站:http://blog.csdn.net/jeffli1993个人签名:打算起手不凡写出鸿篇巨作的人,往往坚持不了完成第一章节。交流QQ群:【编程之美 365234583】http://qm.qq.com/cgi-bin/qm/qr?k=FhFAoaWwjP29_Aonqz
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程与多线程 线程是什么? 线程(Thread)是一个对象(Object)。用来干什么?Java 线程(也称 JVM 线程)是 Java 进程内允许多个同时进行的任务。该进程内并发的任务成为线程(Thread),一个进程里至少一个线程。 Ja
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket在面向对象编程中,编程人员应该在意“资源”。比如?1String hello = &quot;hello&quot;; 在代码中,我们
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第103篇原创 《程序兵法:Java String 源码的排序算法(一)》 文章工程:* JDK 1.8* 工程名:algorithm-core-le
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 目录 一、父子类变量名相同会咋样? 有个小故事,今天群里面有个人问下面如图输出什么? 我回答:60。但这是错的,答案结果是 40 。我知错能改,然后说了下父子类变
作者:泥瓦匠 出处:https://www.bysocket.com/2021-10-26/mac-create-files-from-the-root-directory.html Mac 操作系统挺适合开发者进行写代码,最近碰到了一个问题,问题是如何在 macOS 根目录创建文件夹。不同的 ma
作者:李强强上一篇,泥瓦匠基础地讲了下Java I/O : Bit Operation 位运算。这一讲,泥瓦匠带你走进Java中的进制详解。一、引子在Java世界里,99%的工作都是处理这高层。那么二进制,字节码这些会在哪里用到呢?自问自答:在跨平台的时候,就凸显神功了。比如说文件读写,数据通信,还
1 线程中断 1.1 什么是线程中断? 线程中断是线程的标志位属性。而不是真正终止线程,和线程的状态无关。线程中断过程表示一个运行中的线程,通过其他线程调用了该线程的 方法,使得该线程中断标志位属性改变。 深入思考下,线程中断不是去中断了线程,恰恰是用来通知该线程应该被中断了。具体是一个标志位属性,
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want需求 项目在设计表的时候,要处理并发多的一些数据,类似订单号不能重复,要保持唯一。原本以为来个时间戳,精确到毫秒应该不错了。后来觉得是错了,测试环境下很多一
纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 纯技术交流群 每日推荐 - 技术干货推送 跟着泥瓦匠,一起问答交流 扫一扫,我邀请你入群 加微信:bysocket01
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocketReprint it anywhere u want.文章Points:1、介绍RESTful架构风格2、Spring配置CXF3、三层初设计,实现WebService接口层4、撰写HTTPClient 客户
Writer :BYSocket(泥沙砖瓦浆木匠)什么是回调?今天傻傻地截了张图问了下,然后被陈大牛回答道“就一个回调…”。此时千万个草泥马飞奔而过(逃哈哈,看着源码,享受着这种回调在代码上的作用,真是美哉。不妨总结总结。一、什么是回调回调,回调。要先有调用,才有调用者和被调用者之间的回调。所以在百
Writer :BYSocket(泥沙砖瓦浆木匠)一、什么大小端?大小端在计算机业界,Endian表示数据在存储器中的存放顺序。百度百科如下叙述之:大端模式,是指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加
What is a programming language? Before introducing compilation and decompilation, let&#39;s briefly introduce the Programming Language. Programming la
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:BYSocketFaceBook:BYSocketTwitter :BYSocket泥瓦匠喜欢Java,文章总是扯扯Java。 I/O 基础,就是二进制,也就是Bit。一、Bit与二进制什么是Bit(位)呢?位是CPU
Writer:BYSocket(泥沙砖瓦浆木匠)微博:BYSocket豆瓣:BYSocket一、前言 泥瓦匠最近被项目搞的天昏地暗。发现有些要给自己一些目标,关于技术的目标:专注很重要。专注Java 基础 + H5(学习) 其他操作系统,算法,数据结构当成课外书博览。有时候,就是那样你越是专注方面越