Android绘制折线图记录

实现原理:

首先这个DataView继承View,重写Draw方法,这样当界面展现出来的时候会调用我们自己写的方法,绘制自己想要的图像。

因为这个DataView只负责绘制List集合里面的所有数据,所以外界需要向Dataview里面的list传值,所以我就定义了静态的List变量,方便外界调用。现在我们可以向DataView里面传入数据了,但是如何实时的去动态刷新呢?

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

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

参考代码:自己根据需求进行修改


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);

                    }
                }
            }
        }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中,有多种方法可以实现绘制折线图的功能。一种常用的方法是使用第三方库,如MPAndroidChart、XCL-chart、achartenginee和hellochart等。这些库提供了丰富的功能和易于使用的API,可以帮助开发者快速实现折线图绘制。[2] 如果你想使用hellochart库来实现折线图,首先需要在布局文件中添加一个LineChartView组件。在activity_*.xml文件中,可以添加以下代码来创建LineChartView组件: ```xml <lecho.lib.hellocharts.view.LineChartView android:id="@id/line_chart" android:padding="30dp" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff"/> ``` 接下来,你需要在相应的Activity中创建自定义View,并在其中实现折线图绘制逻辑。你可以参考hellochart库的文档和示例代码,了解如何使用该库来绘制折线图。[3] 另外,如果你对自定义View有一定的了解,也可以自己实现折线图绘制逻辑。你可以通过绘制线条、绘制圆点和绘制阴影等操作来实现折线图的效果。在绘制之前,你可以先观察效果图,确定画布的底层背景、网格背景、折线和圆点的绘制顺序,以及阴影部分的绘制方式。然后,你可以在自定义View中重写onDraw方法,使用Canvas和Paint等类来实现折线图绘制逻辑。[1] 总之,无论是使用第三方库还是自定义View,都可以实现在Android绘制折线图的功能。选择合适的方法取决于你的需求和个人偏好。希望这些信息对你有帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值