Android绘制折线图记录

实现原理:java

首先这个DataView继承View,重写Draw方法,这样当界面展示出来的时候会调用咱们本身写的方法,绘制本身想要的图像。android

由于这个DataView只负责绘制List集合里面的全部数据,因此外界须要向Dataview里面的list传值,因此我就定义了静态的List变量,方便外界调用。如今咱们能够向DataView里面传入数据了,可是如何实时的去动态刷新呢?web

这里须要一个handler,方便检测是否须要更新UI,若是须要更新UI的话,外界就能够向handler发送消息,提示该更新UI,这里须要调用invalidate(),他会调用咱们的onDraw方法。这里我已经在初始化类的时候,将当前的引用交给了本身的一个静态变量,因此外界能够去直接调用handlder。你也可使用单列设计。canvas

每次刺激handler都会调用onDraw一次,都会从新读取list集合里面的数据而后从新绘制,因此你就会看见动态的折线图效果。app

参考代码:本身根据需求进行修改dom

package com.myfirstapp;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AlertDialog;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/** * Created by Lachie on 2017/3/12. */

public class DataView extends View {

    private int screenWidth;
    private int screenHeight;
    private Canvas canvas;
    private Paint paint;

    public static  DataView dataView = null;
    public static final List<Integer> datas = new ArrayList<Integer>();
    private Button close = null;
    private int xNum = 50;
    public DataView(Context context, AttributeSet attrs) {
        super(context, attrs);
        dataView = this;
        close = (Button) findViewById(R.id.dd_close_btn);
    }
    public Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {

            if(datas.size() == 30){//永远保持固定数据
                 datas.remove(0);
            }
            DataView.this.invalidate();//从新draw
            xNum = 50;//重置x轴
        }
    };

   //每次放入数据都会绘制,

    @Override
    protected void onDraw(Canvas canvas) {


        Log.d("t","==============================");

        this.canvas = canvas;//方便后续调用

        screenHeight = getHeight();
        screenWidth = getWidth();

        int value = 500;


        Log.d("t",screenHeight+"");
        Log.d("t",screenWidth+"");

        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        paint.setAntiAlias(true);
        paint.setFakeBoldText(true);

        this.paint = paint;//后续用
        //Y轴
        canvas.drawLine(50,50,50,screenHeight-50,paint);

        //Y轴箭头
        canvas.drawLine(50,50,30,80,paint);
        canvas.drawLine(50,50,80,80,paint);


        //X轴 (x,y) - > (x,y)
        canvas.drawLine(50,screenHeight-50,screenWidth-50,screenHeight-50,paint);
        //X轴箭头
        canvas.drawLine(screenWidth-50,screenHeight-50,screenHeight-80,screenHeight-80,paint);
        canvas.drawLine(screenWidth-50,screenHeight-50,screenHeight-80,screenHeight-50+30,paint);


        //实际的1/5 值
        int block = value /5;
        //模拟的1/5 值
        int vBlock = screenHeight /5;
        Log.d("t","单位长度:" +vBlock);//单位长度

        //画Y刻度
        //没走一个单位长度 描绘一个刻度
        //开始的位置i为y最高点 ; 只要小于50就中止绘制; i每次都会减小一个单位长度
        for(int i= screenHeight - 50,count = 0; i> 50; i-=vBlock,count++){
            Log.d("t","绘制:" +i);
            //x开始 :50 , x结束:向右加10 ; y开始:y的最低点 + 单位长度 , y结束:不变 |
            // 能够想象成 y在向下慢慢移动,而x只是小范围的向左移动,并且每次y降低的时候都是向右移动一下
            canvas.drawLine(50,i,50 + 10,i,paint);
            //在(0,i)的位置写字
            Log.d("t","单位"  + count *block + "");
            canvas.drawText(count *block +"",10,i,paint);

        }
        //若是datas里有数据就绘图
            Log.d("t","数据大小:" + datas.size());
/* * * 每隔一秒存放一个数据,而后从新画UI * * 当存放了2个数据的时候就开始画UI * list集合的第一位画到list集合的第一位 + 1 这样就是一条线了,当划到最后一条线的时候(也就是集合的大小 - 1 的时候,说明是最后一条线)就不画了。 * * */
            if(datas.size() >= 2){
                for(int i=0; i<datas.size(); i++){
                    if(i != datas.size() - 1){
                        Log.d("t",datas.get(i)+"");

                        //传进来的是整数,y轴和现实中相反,因此我须要进行转换 还有比列问题
                        int y = (int)(screenHeight -50 - (datas.get(i)*1.7)) ;
                        int vY = (int)(screenHeight -50 - (datas.get(i+1)*1.7)) ;

                        Log.d("t",y + ", " + vY);
                        Log.d("t",screenHeight -50 + "," + (screenHeight -50));
                        canvas.drawLine(xNum,y,xNum+=20,vY,paint);

                    }
                }
            }
        }
}