Android自定义View——一个通用的折线趋势图组件

为啥说是通用的呢?因为你可以随便放几条折线都行,随便几个说明背景都可以。。。颜色神马都可设置。。。

为啥这么随便?因为公司业务需要,有的折线图是2条折线、2个说明背景色块,有的需要1条折线、3个说明背景,还有个奇葩的是1条折线、4个说明背景,总不能每个都要写一个自定义View吧~

先看效果图:这是两条折线,两个背景图的(拍照不是截图,所以看起来没那么工整,数据我都对比过了,准的一塌糊涂!!!)

先想想思路,一个趋势图需要有以下6个元素:

1,横轴集合 ; 2,纵轴集合; 3,横轴的单位;4,纵轴的单位;5,数据点集合,多少条折线就多少集合;6,说明背景集合。

然后慢慢实现:

写一个表示折线的类:

public class CurveModel {
    //坐标点列表
    private List<Value> curveLineDataList;
    //折线颜色
    private int curveColor;
    //折线描述语句
    private String curveDesc;

    public CurveModel(List<Value> curveLineDataList, int curveColor, String curveDesc) {
        this.curveLineDataList = curveLineDataList;
        this.curveColor = curveColor;
        this.curveDesc = curveDesc;
    }
    ...这儿是get方法...
}

再写一个背景的类:

public class BkgModel {
    //背景的最小值和最大值
    private Value value;
    //背景颜色
    private int color;
    //背景说明文字
    private String desc;

    public BkgModel(Value value, int color, String desc) {
        this.value = value;
        this.color = color;
        this.desc = desc;
    }
    ...这儿是get方法...
}

Value 类在CurveModel 类中表示x、y的数据,在BkgModel 类表示最小值和最大值

public class Value {
    private int x;
    private int y;

    public Value(int x, int y) {
        this.x = x;
        this.y = y;
    }
    ...这儿是get方法...
}

好了,所有Model都写好了,接下来,就是重头戏:绘制VIew

这儿用到了建造者模式:

先看下使用吧,看,是不是非常简单,这样构造一个View真是太方便了:

curveTrendChartView.Builder(getApplicationContext())
        //设置Y轴的数据
        .setY("mmHg", xList, 100.00)
        //设置X轴的数据
        .setX("日期", yList, 10.0)
        //添加背景说明色
        .addBKG(new BkgModel(new Value(8000, 9000), Color.parseColor("#FFF5EE"), "低压正常范围"))
        //再添加背景说明色,如果你还想添加,那就继续add
        .addBKG(new BkgModel(new Value(12000, 14000), Color.parseColor("#E0FFFF"), "高压正常范围"))
        //添加折线
        .addLine(new CurveModel(lowList, Color.parseColor("#006400"), "低压"))
        //我还想添加
        .addLine(new CurveModel(highList, Color.RED,"高压"))
        .build();

接下来是CurveTrendChartView了:

1,主要重写了onDraw方法:

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //绘制背景和说明文字的方法,在该方法初始化了高度的一些变量,所以首先执行该方法
    drawDesc(canvas);
    //绘制Y坐标
    drawYLineText(canvas);
    //绘制X坐标
    drawXLineText(canvas);
    //绘制背景虚线
    drawDottedLine(canvas);
    //绘制每条折线
    drawCurceLine(canvas);
}

2,接下来就是绘制各个模块了,里面对于坐标的绘制真是让我头疼,调了好多次,各种加减乘除,注意,高度是和趋势图相反的:咱们的趋势图是左图,原点在左下。找XY坐标时,要把思想转换为右图,原点在左上。

举例说明:

虚线的高度是这样的:因为要把虚线绘制在中间,所以得加上mYItemHeight / 2,再加上y轴单位和描述框的高度

 i * mYItemHeight + mYItemHeight / 2 + mYUnitHeight + descHeight;

点的高度是这样的:因为虚线是在中间绘制的,所以总高度得减去最上虚线的上半部分和最下虚线的下半部分,然后根据比例求坐标点的位置,最后加上那一大串高度

(mYHeight  - mYItemHeight)* ((curveLineDataList.get(i).getY() - maxData) / (minData - maxD
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值