自定义仪表盘控件(源码中已经改成了自己绘制表盘)

新的任务又来了,这次需要实现一个仪表盘的自定义控件,自定义控件一不常写就手生,这次又巩固下,并且学了一些新知识。

https://developer.android.com/training/custom-views/index.html
Android官方文档中关于自定义控件的教程,在大致了解自定义控件相关内容后,看官方的文档,收获更多,能发现许多其他人文章里并没有写的地方。所以有能力的都看看。

美工设计如下:
这里写图片描述
主要需要实现中间表盘和下方小表盘两个控件(背景色赞)

在开始前,先整理下自定义控件步骤,

  1. 首先需要想好要自定义的控件应该需要哪几个属性,比如对于大表盘,背景什么的美工都帮我设计好了,所以我只需要一个属性 speed,表示当前速度。对于小表盘的话,需要较多,我需要圆的半径,当前数值,数值最大值,数值名称,圆环颜色这几个属性。

  2. 想好了所需要的属性后,我们需要去定义这些属性,在res/values/attrs.xml里定义,定义好类名和属性名。

  3. 创建对应之前定义的类名,生成构造函数,声明所需要的几个属性与paint,并从xml里提取对应的属性值。

  4. 重写onMeasure方法

  5. 重写onDraw方法,完成控件所需的各种绘制

  6. 提供接口,使得可以在代码中更改属性,改变自定义控件状态。

对于自定义view来说,按以上步骤基本就完成了(viewgroup将onDraw换为OnLayout)。

接下来开始第一个控件:

MyWatch

1.首先自定义属性,如上所说我只需要一个speed属性,于是声明

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="MyWatch">
        <attr name="speed" format="integer" />
    </declare-styleable>

</resources>

2.创建对应类,构造函数如下

    public MyWatch(Context context) {
        this(context, null, 0);
    }

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

    public MyWatch(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        /**
         * 获得我们所定义的自定义样式属性
         */
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.MyWatch, defStyleAttr, 0);

        speed = a.getInt(R.styleable.MyWatch_speed, 0);

        paint = new Paint();

        back = BitmapFactory.decodeResource(getResources(), R.drawable.back_watch);
        center = BitmapFactory.decodeResource(getResources(), R.drawable.icon_watch_center);
        arrow = BitmapFactory.decodeResource(getResources(), R.drawable.icon_watch_arrow);


        a.recycle();

    }

把paint的创建,和几个使用到的bitmap的构造都放到构造函数里,而不放在onDraw里,提高每次界面重绘的效率。

3.重写OnMeasure方法
我这没有做太多的计算,由于表盘使用的是一张图片(源码中已经改成了自己绘制),不是手动画的,所以控件大小基本就固定了。
这里具体做法可以看下一个控件。
在这里不做操作的后果是,如果使用wrap_content属性设置长宽,会和使用match_parent一样的效果。参见http://blog.csdn.net/lmj623565791/article/details/24252901/

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);


    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    if (widthMode == MeasureSpec.EXACTLY) {
        width = widthSize;
    } else {
        float needWidth = back.getWidth();
        int desired = (int) (getPaddingLeft() + needWidth 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值