轻松搞定Android中自定义折线图

现在很多的第三方图表虽然用起来比较方便,但感觉有时候项目中需要自己画,为了避免尴尬的状况出现.今天索性屡屡思路来个简单的折线图.
首先自定义View;

//自定义LinearSelfView
public class LinearSelfView extends View {
    private HashMap<Double, Double> map;
    private int marginB;//表格x轴与屏幕底部差
    private int marginLeft;//屏幕坐标原点和表格坐标原点x之差
    private int totalValue;//表格的竖向高度
    private int jvalue;//表格纵向间距
    private boolean isShow;//横竖直线是否显示
    private int bHeight;//坐标原点与屏幕坐标原点之间的高度差
    private Context context;
    private int width;//屏幕的宽度
    private int height;//屏幕的高度
    private ArrayList<Double> xlk;//存放横坐标的集合
    private Point[] mPoints;//
    private Paint paint;//画笔
    private Point endPoint;
    private Point startPoint;
    private ArrayList<Integer> horizontal;//存放横坐标刻度值的集合
    //自定义一个方法,从对应的Activity中传值
    public void setView(Context context, int marginB, int marginLeft, int totalValue, int jvalue) {
        this.marginB = marginB;
        this.marginLeft = marginLeft;
        this.totalValue = totalValue;
        this.jvalue = jvalue;
    }
    //自定义这个方法目的是在于把map值传过来
    public void setPointMap(HashMap<Double, Double> map) {
        this.map = map;
    }
    //复写onMeasure()方法,获取屏幕宽高
      @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //获取屏幕宽
        width = getMeasuredWidth();
        //获取屏幕的高
        height = getMeasuredHeight();
    }
    //自定义这个方法将横坐标每个刻度数传过来
    public void setHorizontal(ArrayList<Integer> horizontal) {
    //写一个异常抛出的方法,便于看错误日志
        if(horizontal.size() != map.size()) throw new RuntimeException("传入的坐标与横坐标刻度数不符 坐标数:"+ map.size() + "刻度数: "+horizontal.size());
        this.horizontal = horizontal;
        //刷新界面
        postInvalidate();
    }
    //复写onDrow()方法
        @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        xlk = Tools.getintFormMap(map);//从小到大保存x的坐标;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);//不建议在onDraw方法里new
        paint.setStrokeWidth(2);
        paint.setStyle(Paint.Style.STROKE);//实心
        paint.setColor(Color.WHITE);
        bHeight = height - marginB;//算出bHeight的值
        int jSize = totalValue / jvalue;//算出y轴总共有的格子数(单元格数);
        for (int i = 0; i < jSize + 1; i++) {
            //画出与x轴平行的几条线(横线)
            canvas.drawLine(marginLeft, bHeight - bHeight / jSize * i, width, bHeight - bHeight / jSize * i, paint);
            //画出y轴的刻度
            canvas.drawText(String.valueOf(jvalue * i), marginLeft / 2, bHeight - bHeight / jSize * i, paint);
        }
        //自定义一个数组将放入轴的各个刻度值
         ArrayList<Integer> xList = new ArrayList<>();
        for (int i = 0; i < xlk.size(); i++) {
             xList.add(marginLeft + (width - marginLeft) / xlk.size() * i);
            int a = marginLeft + (width - marginLeft) / xlk.size() * i;
            Log.d("LinearSelfView", "a:" + a);
            float startX = marginLeft + (width - marginLeft) / horizontal.size() * i;
            float stopX = marginLeft + (width - marginLeft) / horizontal.size() * i;//x刻度
            float stopY = bHeight;
            //与y轴平行的线(竖线)
            canvas.drawLine(startX, 0, stopX, stopY, paint);
            canvas.drawText(String.valueOf(horizontal.get(i)), marginLeft + (width - marginLeft) / horizontal.size() * i, bHeight + 10, paint);
        }
        mPoints = getPoints(xList);
        //连线
        paint.setColor(ContextCompat.getColor(getContext(), R.color.colorLine));
        drawLine(mPoints, canvas, paint);
        //画点
        paint.setColor(Color.RED);
        paint.setStyle(Paint.Style.FILL);
        for (int j = 0; j < mPoints.length; j++) {
            canvas.drawRect(pointRect(mPoints[j]), paint);
        }
    }
    //画的小方块(坐标点的周围)
    int RECT_SIZE = 3;
    //对点的左右进行运算
    private RectF pointRect(Point Point) {
        return new RectF(Point.x - RECT_SIZE, Point.y - RECT_SIZE, Point.x + RECT_SIZE, Point.y + RECT_SIZE);
    }
    private void drawLine(Point[] mPoints2, Canvas canvas, Paint paint) {
        //利用相邻的俩个点进行连线
        startPoint = new Point();
        endPoint = new Point();
        for (int i = 0; i < mPoints2.length - 1; i++) {
            startPoint = mPoints2[i];
            endPoint = mPoints2[i + 1];
            //利用所有点的横纵坐标进行连线
            canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint);
        }
    }
    //TODO 随着传入的map值的多少不一样 ,需要改变横坐标的个数
    private Point[] getPoints(ArrayList<Integer> xList) {
        //得到点的数组(横纵坐标)
        Point[] points = new Point[xList.size()];
        for (int i = 0; i < points.length; i++) {
            int py = (int) (bHeight - (bHeight * (map.get(xlk.get(i)) / totalValue)));//y的坐标
            points[i] = new Point(xList.get(i), py);
        }
        return points;
    }
}
Activity里的只需要将map的值和自定义方法传入即可
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值