android实现简单仪表盘效果

本文实例为大家分享了android实现简单仪表盘效果的具体代码,供大家参考,具体内容如下

实现这个效果:

中间的文字很好写,外层的进度条就需要自定义控件了,代码如下:

public class CirCleProgressBar extends View {

    private Paint circlePaint;
    private Paint textPaint;
    private int circleColor;//圆弧颜色
    private int circleBgColor;//圆弧背景颜色
    private float circleWidth;//圆弧宽度
    private float circleBgWidth;//圆弧背景宽度
    private int textColor;//字体颜色
    private float textSize;//字体大小
    private int totalAngle;//总角度
    private int startAngle;//开始角度
    private float currentProgress;//当前进度
    private float maxProgress;//最大进度
    private float section;//分段

    private float currentAngle;//当前角度
    private float lastAngle;
    private ValueAnimator progressAnimator;//圆弧动画
    private int duration = 1000;//动画时长
    private  boolean isDefaultText;//是否设置文字显示的值
    private  String mTextValue;//字体显示的值

    public CirCleProgressBar(Context context) {
        this(context, null);
    }

    public CirCleProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CirCleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        circlePaint = new Paint();
        textPaint = new Paint();
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CirCleProgressBar);
        circleColor = typedArray.getColor(R.styleable.CirCleProgressBar_circle_color, Color.RED);
        circleBgColor = typedArray.getColor(R.styleable.CirCleProgressBar_circle_bg_color, Color.YELLOW);
        circleWidth = typedArray.getDimension(R.styleable.CirCleProgressBar_circle_width, 2);
        circleBgWidth = typedArray.getDimension(R.styleable.CirCleProgressBar_circle_bg_width, 2);
        textColor = typedArray.getColor(R.styleable.CirCleProgressBar_text_color, Color.BLUE);
        textSize = typedArray.getDimension(R.styleable.CirCleProgressBar_text_size, 10);
        totalAngle = typedArray.getInteger(R.styleable.CirCleProgressBar_total_angle, 360);
        startAngle = typedArray.getInteger(R.styleable.CirCleProgressBar_start_angle, 0);
        currentProgress = typedArray.getFloat(R.styleable.CirCleProgressBar_current_progress, 0);
        maxProgress = typedArray.getFloat(R.styleable.CirCleProgressBar_max_progress, 100);
        setCurrentProgress(currentProgress);
        setMaxProgress(maxProgress);
        //
        typedArray.recycle();
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 画最外层的大圆环
         */
        int centre = getWidth() / 2; // 获取圆心的x坐标
        int radius = (int) (centre - circleWidth / 2) - 2; // 圆环的半径
        circlePaint.setColor(circleBgColor);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setAntiAlias(true);
        circlePaint.setStrokeCap(Paint.Cap.ROUND);// 圆头
        circlePaint.setStrokeWidth(circleBgWidth);
        RectF oval = new RectF(centre - radius - 1, centre - radius - 1, centre + radius + 1, centre + radius + 1); // 用于定义的圆弧的形状和大小的界限
        //背景圆
        canvas.drawArc(oval, startAngle, totalAngle, false, circlePaint);
        //数据圆
        circlePaint.setStrokeWidth(circleWidth);
        circlePaint.setColor(circleColor);
        canvas.drawArc(oval, startAngle, currentAngle, false, circlePaint);
        //
        textPaint.setAntiAlias(true);
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);
        float textWidth = textPaint.measureText((int) currentProgress + "");
        if(!isDefaultText) {
            canvas.drawText(String.valueOf((int)currentProgress), centre - textWidth / 2, centre + textSize / 2, textPaint);
        }else {
            canvas.drawText(mTextValue, centre - textWidth / 2, centre + textSize / 2, textPaint);
        }
        //
        invalidate();
    }

    public float getMaxProgress(){
        return maxProgress;
    }

    public void setMaxProgress(float maxProgress){
        if(maxProgress < 0){
            throw new IllegalArgumentException("max not less than 0");
        }
        this.maxProgress = maxProgress;
        section = totalAngle / maxProgress;
    }

    public void setAnimationDuration(int duration){
        this.duration = duration;
    }

    public void setCurrentProgress(float progress){
        if(progress >= 0){
            this.currentProgress = progress;
            if(progress > maxProgress){
                progress = maxProgress;
            }
            lastAngle = currentAngle;
            setAnimation(lastAngle, progress * section, duration);
        }

    }

    private void setAnimation(float last, float current, int duration){
        progressAnimator = ValueAnimator.ofFloat(last, current);
        progressAnimator.setDuration(duration);
        progressAnimator.setTarget(currentAngle);
        progressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentAngle = (float) valueAnimator.getAnimatedValue();
                currentProgress = currentAngle / section;
            }
        });
        progressAnimator.start();
    }

    public int getCircleColor() {
        return circleColor;
    }

    public void setCircleColor(int circleColor) {
        this.circleColor = circleColor;
    }

    public int getCircleBgColor() {
        return circleBgColor;
    }

    public void setCircleBgColor(int circleBgColor) {
        this.circleBgColor = circleBgColor;
    }

    public float getCircleWidth() {
        return circleWidth;
    }

    public void setCircleWidth(float circleWidth) {
        this.circleWidth = circleWidth;
    }

    public float getCircleBgWidth() {
        return circleBgWidth;
    }

    public void setCircleBgWidth(float circleBgWidth) {
        this.circleBgWidth = circleBgWidth;
    }

    public int getTextColor() {
        return textColor;
    }

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

    public float getTextSize() {
        return textSize;
    }

    public void setTextSize(float textSize) {
        this.textSize = textSize;
    }

    /**
     * @param isText 为true,自定义设置字体显示
     * @param text
     */
    public  void setText(boolean isText,String text){
        isDefaultText = isText;
        mTextValue = text;
    }
}

需要在attrs中添加:

<declare-styleable name="CirCleProgressBar">
        <attr name="circle_color" format="color"/>
        <attr name="circle_bg_color" format="color"/>
        <attr name="circle_width" format="dimension"/>
        <attr name="circle_bg_width" format="dimension"/>
        <attr name="text_color" format="color"/>
        <attr name="text_size" format="dimension"/>
        <attr name="total_angle" format="integer"/>
        <attr name="start_angle" format="integer"/>
        <attr name="current_progress" format="float"/>
        <attr name="max_progress" format="float"/>
</declare-styleable>

使用方法:

在布局文件中直接引用

<com.fm.newcinema.view.CirCleProgressBar
                android:id="@+id/cc_cinema_sentiment"
                android:layout_width="139dp"
                android:layout_height="99dp"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="8dp"
                app:circle_bg_color="@color/gray_line_ff"
                app:circle_bg_width="10dp"
                app:circle_color="@color/main_blue"
                app:circle_width="10dp"
                app:max_progress="100"
                app:start_angle="160"
                app:text_color="@color/white_ff"
                app:text_size="@dimen/size_30px"
                app:total_angle="221"/>

其中app:circle_bg_color表示进度条底层的颜色,app:circle_color表示进度条上层的颜色,app:circle_bg_width表示进度条底层的宽度,app:circle_width表示进度条上层的宽度,app:max_progress="100"表示进度条最大进度是100,app:start_angle表示开始的角度,就是进度条从哪个角度开始画,如下图所示

app:total_angle表示整个进度条所需的角度.
在代码中设置旋转的角度,图中进度为30%,由于在布局文件中设置的最大进度是100`app:max_progress="100",所以进行如下设置peocess.setCurrentProgress(30f)
默认情况下,进度条中间显示进度条的值,如果需要自己写值的画,调用这个方法:process.setText(true, "中间的字");

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android自定义View实现渐变色仪表盘

    前言:最近一直在学自定义View的相关知识,感觉这在Android中还是挺难的一块,当然这也是每个程序员必经之路,正好公司项目要求实现类似仪表盘的效果用于直观的显示公司数据,于是就简单的写了个demo,记录实现的过程.上篇<Android自定义View实现圆弧进度效果>简单记录了圆弧及文字的绘制,渐变色的仪表盘效果将更加升入的介绍canvas及paint的使用(如画布旋转,paint的渐变色设置等). 知识梳理 1.圆弧渐变色(SweepGradient) 2.圆弧上刻度绘制 3.指针指示当前

  • Android自定义view之仿支付宝芝麻信用仪表盘示例

    自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="RoundIndicatorView"> <!--最大数值--> <attr name="maxNum" form

  • Android实现仪表盘效果

    本文实例为大家分享了Android实现仪表盘效果的具体代码,供大家参考,具体内容如下 仪表盘效果,圆弧可变色,效果图如下: 通过自定义view实现,代码如下: public class DashboardView extends View { private int mRadius; // 画布边缘半径(去除padding后的半径) private int mStartAngle = 150; // 起始角度 private int mSweepAngle = 240; // 绘制角度 priv

  • Android自定义View制作仪表盘界面

    前言 最近我跟自定义View杠上了,甚至说有点上瘾到走火入魔了.身为菜鸟的我自然要查阅大量的资料,学习大神们的代码,这不,前两天正好在郭神在微信公众号里推送一片自定义控件的文章--一步步实现精美的钟表界面.正适合我这种菜鸟来学习,闲着没事,我就差不多依葫芦画瓢也写了一个自定义表盘View,现在纯粹最为笔记记录下来.先展示下效果图: 下面进入正题 自定义表盘属性 老规矩,先在attrs文件里添加表盘自定义属性 <declare-styleable name="WatchView"&

  • Android自定义View仿支付宝芝麻信用分仪表盘

    先看下iOS的芝麻信用分截图 这是我做的效果,还是有点差距的 支付宝9.9版本芝麻信用分的实现 首先初始化各种画笔,默认的size,padding,小圆点. (因为实在找不到原版芝麻信用的带点模糊效果的小圆点,所以只好用这个代替) //View的默认大小 defaultSize = dp2px(250); //默认Padding大小 arcDistance = dp2px(14); //外层圆环画笔 mMiddleArcPaint = new Paint(Paint.ANTI_ALIAS_FLA

  • android实现简单仪表盘效果

    本文实例为大家分享了android实现简单仪表盘效果的具体代码,供大家参考,具体内容如下 实现这个效果: 中间的文字很好写,外层的进度条就需要自定义控件了,代码如下: public class CirCleProgressBar extends View { private Paint circlePaint; private Paint textPaint; private int circleColor;//圆弧颜色 private int circleBgColor;//圆弧背景颜色 pr

  • android实现简单圆弧效果

    最近项目完成就开始搞一些有用没用的东西,以前面试的时候有人问我那种圆弧效果怎么做,还问我翻牌效果,我只看过,没有做过,现在有空了,而且想到可能会用到就做个简单的 圆弧很简单,自定义个View,创建个Paint,设置 arcPaint.setStyle(Paint.Style.STROKE)再设置圆弧的宽,再在onDraw内调用canvas.drawArc()就好了 现在只做一个带刻度的圆弧和一个开口地方是圆角的圆弧.其他各种效果以后再摸索 ArcView.java public class Ar

  • Android编程简单实现雷达扫描效果

    本文实例讲述了Android编程简单实现雷达扫描效果.分享给大家供大家参考,具体如下: 在eoe看到有一篇关于雷达扫描的文章,然后看了下,很简单,但是觉得还有很多可以优化的地方,下面贴出来 package com.example.wave; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; im

  • 简单实现Android弹出菜单效果

    本文实例为大家分享了Android弹出菜单效果的具体代码,供大家参考,具体内容如下 功能描述:用户单击按钮弹出菜单.当用户选择一个菜单项,会触发MenuItemClick事件并让弹出的菜单消失:如果用户在菜单外单击,则直接消失弹出的菜单.当菜单消失时,会引发DismissEvent事件(利用此事件可在菜单消失时做一些后续处理). 1.运行效果 2.添加菜单项 在Resources文件夹下添加一个menu子文件夹,然后在此子文件夹下添加一个名为demo07_popup_menu.xml的文件: <

  • Android实现简单水波纹效果

    本文为大家分享了Android实现水波纹效果展示的具体代码,供大家参考,具体内容如下 一.效果 二.实现原理 自定义view,使用Path和贝塞尔曲线绘制,然后不断刷新,并且改变X.Y的值 主要知识点rQuadTo的使用 三.实现 WaveView.java public class WaveView extends View { private Paint mPaint; private final Path mPath; //波长 private int wavelength = 500;

  • android实现简单进度条ProgressBar效果

    本文实例为大家分享了android实现简单进度条ProgressBar的具体代码,供大家参考,具体内容如下 记录一下今天学习的进度条ProgressBar 1.在布局文件中添加ProgressBar <ProgressBar         android:id="@+id/progressbar"         android:layout_width="match_parent"         android:layout_height="w

  • Android实现左右滑动效果的方法详解

    本示例演示在Android中实现图片左右滑动效果. 关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来就让我们开始实现这种效果.为了方便大家理解,我们先来看一下效果图:主要效果图如下图:    接下来我们看一下程序结构图: MainActivity文件中代码: 复制代码 代码如下: package com.android.flip;import android.app.Activity;import a

  • Android编程ViewPager回弹效果实例分析

    本文实例讲述了Android编程ViewPager回弹效果.分享给大家供大家参考,具体如下: 其实在我们很多应用中都看到当ViewPager滑到第一页或者最后一页的时候,如果再滑动的时候,就会有一个缓冲的过程,也就是回弹效果.之前在研究回弹效果的时候,也顺便实现了ViewPager的回弹效果,其实也很简单,一下是实现代码,注释比较少: package com.freesonfish.viewpager_2; import android.content.Context; import andro

  • Android编程实现抽屉效果的方法示例

    本文实例讲述了Android编程实现抽屉效果的方法.分享给大家供大家参考,具体如下: 今天在手机上实现了抽屉效果,其实很简单,但是效果却很酷. 首先在layout 下设置xml布局文件 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:l

随机推荐