android绘制折线图绘制

rq300622 9年前

折线图的实现方法在github上有很多开源的程序,但是对于初学者来讲,简单一点的教程可能更容易入门,下面的文章来自csdn的阳光的小强,或许有用(没仔细阅读,大概看了下文章的结构清晰,折线图的效果也还好)。

转载自阳光的小强的博客http://blog.csdn.net/dawanganban/article/details/31445249

 

有时候我们在项目中会遇到使用折线图等图形,Android的开源项目中为我们提供了很多插件,但是很多时候我们需要根据具体项目自定义这些图表,这一篇文章我们一起来看看如何在Android中使用Canvas绘制折线图。先看看绘制的效果:

实现原理很简单,我就直接给出代码:

package com.example.testcanvasdraw;                                                                     import java.util.ArrayList;   import java.util.List;   import java.util.Random;                                                                     import android.content.Context;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.os.Handler;   import android.os.Message;   import android.util.AttributeSet;   import android.view.View;                                                                     public class MyView extends View{       private int XPoint = 60;       private int YPoint = 260;       private int XScale = 8;  //刻度长度       private int YScale = 40;       private int XLength = 380;       private int YLength = 240;                                                                             private int MaxDataSize = XLength / XScale;                                                                             private List<Integer> data = new ArrayList<Integer>();                                                                                                                                                                                                                     private String[] YLabel = new String[YLength / YScale];                                                                             private Handler handler = new Handler(){           public void handleMessage(Message msg) {               if(msg.what == 0x1234){                   MyView.this.invalidate();               }           };       };       public MyView(Context context, AttributeSet attrs) {           super(context, attrs);           for(int i=0; i<YLabel.length; i++){               YLabel[i] = (i + 1) + "M/s";           }                                                                                     new Thread(new Runnable() {                                                                                             @Override               public void run() {                   while(true){                       try {                           Thread.sleep(1000);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                       if(data.size() >= MaxDataSize){                           data.remove(0);                       }                       data.add(new Random().nextInt(4) + 1);                       handler.sendEmptyMessage(0x1234);                   }               }           }).start();       }                                                                             @Override       protected void onDraw(Canvas canvas) {           super.onDraw(canvas);           Paint paint = new Paint();           paint.setStyle(Paint.Style.STROKE);           paint.setAntiAlias(true); //去锯齿           paint.setColor(Color.BLUE);                                                                                     //画Y轴           canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint);                                                                                     //Y轴箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint-YLength + 6, paint);  //箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint-YLength + 6 ,paint);                                                                                     //添加刻度和文字           for(int i=0; i * YScale < YLength; i++) {               canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i * YScale, paint);  //刻度                                                                                             canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);//文字           }                                                                                     //画X轴           canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint);           System.out.println("Data.size = " + data.size());           if(data.size() > 1){               for(int i=1; i<data.size(); i++){                   canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) * YScale,                            XPoint + i * XScale, YPoint - data.get(i) * YScale, paint);               }           }       }   }

上面绘制折线部分我们还有一种方式同样可以实现:

if(data.size() > 1){       Path path = new Path();       path.moveTo(XPoint, YPoint - data.get(0) * YScale);       for(int i=1; i<data.size(); i++){           path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale);       }       canvas.drawPath(path, paint);   }

下面我们将上面代码修改,让折线下面的区域颜色填充

package com.example.testcanvasdraw;                                                import java.util.ArrayList;   import java.util.List;   import java.util.Random;                                                import android.content.Context;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.graphics.Path;   import android.os.Handler;   import android.os.Message;   import android.util.AttributeSet;   import android.view.View;   /**   *    * @author 阳光小强   * http://blog.csdn.net/dawanganban   *   */   public class MyView extends View {       private int XPoint = 60;       private int YPoint = 260;       private int XScale = 8; // 刻度长度       private int YScale = 40;       private int XLength = 380;       private int YLength = 240;                                                    private int MaxDataSize = XLength / XScale;                                                    private List<Integer> data = new ArrayList<Integer>();                                                    private String[] YLabel = new String[YLength / YScale];                                                    private Handler handler = new Handler() {           public void handleMessage(Message msg) {               if (msg.what == 0x1234) {                   MyView.this.invalidate();               }           };       };                                                    public MyView(Context context, AttributeSet attrs) {           super(context, attrs);           for (int i = 0; i < YLabel.length; i++) {               YLabel[i] = (i + 1) + "M/s";           }                                                        new Thread(new Runnable() {                                                            @Override               public void run() {                   while (true) {                       try {                           Thread.sleep(1000);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                       if (data.size() >= MaxDataSize) {                           data.remove(0);                       }                       data.add(new Random().nextInt(4) + 1);                       handler.sendEmptyMessage(0x1234);                   }               }           }).start();       }                                                    @Override       protected void onDraw(Canvas canvas) {           super.onDraw(canvas);           Paint paint = new Paint();           paint.setStyle(Paint.Style.STROKE);           paint.setAntiAlias(true); // 去锯齿           paint.setColor(Color.BLUE);                                                        // 画Y轴           canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint);                                                        // Y轴箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength                   + 6, paint); // 箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength                   + 6, paint);                                                        // 添加刻度和文字           for (int i = 0; i * YScale < YLength; i++) {               canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i                       * YScale, paint); // 刻度                                                            canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);// 文字           }                                                        // 画X轴           canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint);                                                        // 绘折线           /*           * if(data.size() > 1){ for(int i=1; i<data.size(); i++){           * canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *           * YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint); }           * }           */           paint.setStyle(Paint.Style.FILL);           if (data.size() > 1) {               Path path = new Path();               path.moveTo(XPoint, YPoint);               for (int i = 0; i < data.size(); i++) {                   path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale);               }               path.lineTo(XPoint + (data.size() - 1) * XScale, YPoint);               canvas.drawPath(path, paint);           }       }   }

上面的效果有时候还是达不到我们的要求,我们将代码修改后效果如下:

package com.example.testcanvasdraw;                             import java.util.ArrayList;   import java.util.List;   import java.util.Random;                             import android.content.Context;   import android.graphics.Canvas;   import android.graphics.Color;   import android.graphics.Paint;   import android.graphics.Path;   import android.os.Handler;   import android.os.Message;   import android.util.AttributeSet;   import android.view.View;                             /**   *    * @author 阳光小强 http://blog.csdn.net/dawanganban   *    */   public class MyView extends View {       private int XPoint = 60;       private int YPoint = 260;       private int XScale = 8; // 刻度长度       private int YScale = 40;       private int XLength = 380;       private int YLength = 240;                                 private int MaxDataSize = XLength / XScale;                                 private List<Integer> data = new ArrayList<Integer>();                                 private String[] YLabel = new String[YLength / YScale];                                 private Handler handler = new Handler() {           public void handleMessage(Message msg) {               if (msg.what == 0x1234) {                   MyView.this.invalidate();               }           };       };                                 public MyView(Context context, AttributeSet attrs) {           super(context, attrs);           for (int i = 0; i < YLabel.length; i++) {               YLabel[i] = (i + 1) + "M/s";           }                                     new Thread(new Runnable() {                                         @Override               public void run() {                   while (true) {                       try {                           Thread.sleep(1000);                       } catch (InterruptedException e) {                           e.printStackTrace();                       }                       if (data.size() >= MaxDataSize) {                           data.remove(0);                       }                       data.add(new Random().nextInt(4) + 1);                       handler.sendEmptyMessage(0x1234);                   }               }           }).start();       }                                 @Override       protected void onDraw(Canvas canvas) {           super.onDraw(canvas);           Paint paint = new Paint();           paint.setStyle(Paint.Style.STROKE);           paint.setAntiAlias(true); // 去锯齿           paint.setColor(Color.BLUE);                                     // 画Y轴           canvas.drawLine(XPoint, YPoint - YLength, XPoint, YPoint, paint);                                     // Y轴箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint - 3, YPoint - YLength                   + 6, paint); // 箭头           canvas.drawLine(XPoint, YPoint - YLength, XPoint + 3, YPoint - YLength                   + 6, paint);                                     // 添加刻度和文字           for (int i = 0; i * YScale < YLength; i++) {               canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + 5, YPoint - i                       * YScale, paint); // 刻度                                         canvas.drawText(YLabel[i], XPoint - 50, YPoint - i * YScale, paint);// 文字           }                                     // 画X轴           canvas.drawLine(XPoint, YPoint, XPoint + XLength, YPoint, paint);                                     // 绘折线           /*           * if(data.size() > 1){ for(int i=1; i<data.size(); i++){           * canvas.drawLine(XPoint + (i-1) * XScale, YPoint - data.get(i-1) *           * YScale, XPoint + i * XScale, YPoint - data.get(i) * YScale, paint); }           * }           */           paint.setColor(Color.RED);           paint.setStrokeWidth(5);                                     Paint paint2 = new Paint();           paint2.setColor(Color.BLUE);           paint2.setStyle(Paint.Style.FILL);           if (data.size() > 1) {               Path path = new Path();               Path path2 = new Path();               path.moveTo(XPoint, YPoint - data.get(0) * YScale);               path2.moveTo(XPoint, YPoint);               for (int i = 0; i < data.size(); i++) {                   path.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale);                   path2.lineTo(XPoint + i * XScale, YPoint - data.get(i) * YScale);               }               path2.lineTo(XPoint + (data.size() - 1) * XScale, YPoint);               canvas.drawPath(path, paint);               canvas.drawPath(path2, paint2);           }       }   }