自定义View实现仪表盘(账户安全)

原创 2016年08月28日 22:29:35

转载请注明出处:http://blog.csdn.net/magic_jss/article/details/52348392
群里聊天一哥们发的一个自定义View感觉很perfection,于是就根据他发的图写了个类似的效果。一个仪表盘,描述用户的账号安全等级。希望能够帮助到需要类似效果的猿/媛们,如果存在什么问题恳请指正!

效果图:

这里写图片描述

模拟器上运行效果可能有点差,真机上就比较清晰了。

1、自定义View

废话少说,直接上码;

/**
 * Created by magic on 2016年7月28日.账户安全 仪表盘view
 */
@SuppressLint({ "DrawAllocation", "ResourceAsColor" })
public class DashBoardView extends View {

    private Context context;
    // 圆
    private Paint mPaint;
    // 弧
    private Paint mPaintArc;
    // 弧的外接矩形
    private RectF rectFArc, rectFArc2;
    // text
    private Paint mPaintText;
    // line
    private Paint mPaintLine;
    // 指针路径
    private Path path;
    // 宽、高
    private float width, height;
    private float radius, arcWidth, arcWidth2, arcStrokeWidth, pointerLength,
            lineLength;
    // 设置旋转角度
    public float degrees = 0;
    private float paddingLeft, paddingTop, paddingRight, paddingBottom;

    // 底部描述文字
    private String desc;

    public DashBoardView(Context context) {
        super(context);
        this.context = context;
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    public DashBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(context.getResources().getColor(R.color.zs));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        mPaintArc = new Paint();
        mPaintArc.setStyle(Paint.Style.STROKE);
        mPaintArc.setAntiAlias(true);

        mPaintLine = new Paint();
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        mPaintLine.setStyle(Paint.Style.FILL);
        mPaintLine.setAntiAlias(true);

        path = new Path();

        mPaintText = new Paint();
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        mPaintText.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wMode = MeasureSpec.getMode(widthMeasureSpec);
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);
        int hSize = MeasureSpec.getSize(heightMeasureSpec);

        // 处理宽高为 wrap_content的情况
        if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (wMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, hSize);
        } else if (hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(wSize, 200);
        }

        // 获取padding
        paddingLeft = getPaddingLeft();
        paddingTop = getPaddingTop();
        paddingRight = getPaddingRight();
        paddingBottom = getPaddingBottom();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.width = w - paddingLeft - paddingRight;
        this.height = h - paddingTop - paddingBottom;// 640 850 360-360

        if (width <= height) {
            arcWidth = width / 2;
        } else {
            arcWidth = height / 2;
        }

        arcStrokeWidth = (10 / 180f) * arcWidth;
        radius = 15 / 180f * arcWidth;
        pointerLength = 110 / 180f * arcWidth;
        lineLength = 15 / 180f * arcWidth;

        mPaintArc.setStrokeWidth(arcStrokeWidth);
        arcWidth2 = arcWidth - mPaintArc.getStrokeWidth();
        mPaintLine.setStrokeWidth(2 / 180f * arcWidth);
        mPaintText.setTextSize(20 / 180f * arcWidth);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(width / 2 + paddingLeft, height / 2 + paddingTop);
        canvas.drawCircle(0, 0, radius, mPaint);

        rectFArc = new RectF(-arcWidth, -arcWidth, arcWidth, arcWidth);
        rectFArc2 = new RectF(-arcWidth2, -arcWidth2, arcWidth2, arcWidth2);

        mPaintArc.setColor(context.getResources().getColor(R.color.mainTextBlack));
        canvas.drawArc(rectFArc, 165, 210, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.hs));
        canvas.drawArc(rectFArc2, 165, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawArc(rectFArc2, 235, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.ls));
        canvas.drawArc(rectFArc2, 305, 70, false, mPaintArc);

        float startXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth);
        float stopXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth - lineLength);
        float startXText = -mPaintText.measureText("中") / 2;
        float stopXText = -(arcWidth2 - (1 / 2) * mPaintArc.getStrokeWidth() - (2.5f) * lineLength);

        canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawText("中", startXText, stopXText, mPaintText);

        mPaintLine.setColor(context.getResources().getColor(R.color.hs));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(-35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.hs));
                canvas.drawText("低", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }

        canvas.rotate(105);
        mPaintLine.setColor(context.getResources().getColor(R.color.ls));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.ls));
                canvas.drawText("高", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }

        canvas.rotate(-105);
        mPaintText.setColor(context.getResources().getColor(R.color.mainTextBlack));
        canvas.drawText(desc, -mPaintText.measureText(desc) / 2, pointerLength,mPaintText);
        // 画笔坐标系旋转
        canvas.rotate(-105 + degrees);
        // 绘制指针
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        path.moveTo(radius / 2, 0);
        path.lineTo(0, -pointerLength);
        path.lineTo(-radius / 2, 0);
        canvas.drawPath(path, mPaintLine);
    }

    /**
     * 设置旋转角度
     */
    public void setDegrees(float degrees) {
        this.degrees = degrees;
        invalidate();
    }

    /**
     * 获取旋转角度
     */
    public float getDegrees() {
        return this.degrees;
    }

    /**
     * 设置底部描述
     */
    public void setTextDesc(String desc){
        this.desc=desc;
        invalidate();
    }
}

直接继承View需要处理宽高为包含内容,存在padding的情况。其中,根据在某个定值的情况下动态计算中心圆半径、指针长度、环形StrokeWidth等等,代码比较简单,直接看注释就OK!

2、xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:magic="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <com.mars.customview.DashBoardView
        android:id="@+id/dashBoardView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:padding="50dp" />

</LinearLayout>

未添加自定义属性,若有相关需求可自行添加。

3、Activity中使用

/**
 * Created by magic on 2016年7月28日.
 */
public class MainActivity extends Activity {

    DashBoardView dashBoardView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        dashBoardView = (DashBoardView) findViewById(R.id.dashBoardView);

        // 账户安全 仪表盘
        ObjectAnimator animator = ObjectAnimator.ofFloat(dashBoardView,"degrees", 175);
        animator.setDuration(3000);
        // 设置插值器
        animator.setInterpolator(new DecelerateInterpolator());
        animator.start();

        dashBoardView.setTextDesc("你的账户等级  高");

    }

}

整个Demo下载地址:http://download.csdn.net/detail/magic_jss/9616384

END!

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

android 自定义View 仪表盘 DashboardView 的实现

有天上班,老板突然扔给我一张图,说:这个东西能不能做一下。我说应该可以。然后老板那就没有下文了,我想既然问了,那我就抽空做一下。当我做出来的时候去找老板,我说上次你给我发的那个图,我已经做出来了,您要...

自定义View:圆形仪表盘,实现展示不同级别范围

一、前言公司项目需要实现一个类似圆形仪表盘,展示不同级别范围的View,本着不重复造轮子的原则,Google了一番愣是没有找到到合适的,于是只能撸起袖子自己干。先来看最终效果图:文末会附上源码链接。二...

Android自定义View----时钟/仪表盘的简单实现

1.自定义属性 在资源文件夹下values目录中创建一个attrs.xml文件,文件结构如下所示,declare-styleable是自定义view的名字,atrr标签就是我们要自定义的一些属性, ...

自定义view 仪表盘

  • 2017年01月09日 14:54
  • 18KB
  • 下载

手把手带你画一个 时尚仪表盘 Android 自定义View

标签: 仪表盘Android自定义view 2016-01-06 15:29 5576人阅读 评论(22) 收藏 举报 本文章已收录于: 分类: 自定义vie...

MeterView自定义View进度条仪表盘

  • 2016年10月31日 17:47
  • 25.46MB
  • 下载

自定义view-仪表盘

  • 2017年03月22日 11:24
  • 134KB
  • 下载

Android自定义view之仿支付宝芝麻信用仪表盘 ---by ccy

自定义view练习 仿支付宝芝麻信用的仪表盘 对比图: 首先是自定义一些属性,可自己再添加,挺基础的,上代码 ...
  • ccy0122
  • ccy0122
  • 2016年11月20日 16:37
  • 4784
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自定义View实现仪表盘(账户安全)
举报原因:
原因补充:

(最多只允许输入30个字)