使用Android的canvas,画折线图:代码为:

package spt.view;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.DashPathEffect;import android.graphics.Paint;import android.graphics.Path;import android.graphics.PathEffect;import android.util.Log;import android.view.View;/** * 为了扩展不同分辨率手机的兼容性,百分比和一些重要变量设置为final,其他可变变量设置为成员变量. *  * @author Administrator *  */@SuppressLint("DrawAllocation")public class BrokenLineView extends View {// 计算相对比例时,均使用边距margin为依照(值与比例结果成反比).// 画轴线时,箭头所占比例.private static final int ARROW_PECENT = 10;// x,y轴坐标点文字的比例.private static final int X_TEXT_PECENT = 10;private static final int Y_TEXT_PECENT = 10;// 标题文字的比例.private static final int TITLE_TEXT_PECENT = 5;// 默认坐标轴值.private static final String[] X_LABLE = { "a", "b", "c", "d", "e", "f", "g" };private static final String[] Y_LABLE = { "0", "50", "100", "150", "200","250", "300" };// 数据点圆的半径.private static final int dataRadius = 10;// x,y轴坐标点数字的位置偏离轴线的距离.private int xTextDistanceAxis = 20;private int yTextDistanceAxis = 30;// 数据点数值文字相对于数据点的高度值.private int dataTextAboveCircle = 25;// 边距(也不能为final,因为可能用户可能根据不同条件设置不同间距.private int margin = 100;// X,Y轴的单位长度private int xScale = 20;private int yScale = 20;// 标题的高度.private String title;// 标题距离最顶行线的y距离.private int titleHeight = 20;// 原点坐标private int x0Point;private int y0Point;// X,Y轴上面的显示文字private String[] xLabel = null;private String[] yLabel = null;// 曲线数据private int[] data = null;public BrokenLineView(Context context, String title, String[] xLabel,String[] yLabel, int[] data) {super(context);this.title = title;// 若传递空值,则使用默认的值.this.xLabel = (xLabel == null ? X_LABLE : xLabel);this.yLabel = (yLabel == null ? Y_LABLE : yLabel);if (data == null)throw new RuntimeException("data cannot null:");this.data = data;}public BrokenLineView(Context context) {this(context, null, X_LABLE, Y_LABLE, null);}// 设置坐标原点位置和轴线上的单位长度.public void init() {x0Point = margin; // x0.y0Point = getHeight() - margin; // y0.xScale = (getWidth() - 2 * margin) / (this.xLabel.length - 1);yScale = (getHeight() - 2 * margin) / (this.yLabel.length - 1);}public int getMargin() {return margin;}public void setMargin(int margin) {if (margin < 0)throw new RuntimeException("间距不能为负数:" + margin);this.margin = margin;}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(Color.BLACK); // 背景色.Paint p = new Paint();p.setStyle(Paint.Style.STROKE); // 设置轴线的的外框的样式“空心”(STROKE).p.setAntiAlias(true); // 抗锯齿p.setColor(Color.WHITE);p.setStrokeWidth(2); // 设置轴线的的外框的宽度.init();drawYAxis(canvas, p);drawXAxis(canvas, p);drawHorizontalLine(canvas);drawData(canvas);}// x向线private void drawHorizontalLine(Canvas canvas) {Paint paint = new Paint();paint.setStyle(Paint.Style.STROKE);paint.setColor(Color.GRAY);Path path = new Path();// 先画长度为1的实线,然后长度为10的空白,再画长度为1实线,再画长度为10的空白;最后一个是是偏移量,可不理会.PathEffect effects = new DashPathEffect(new float[] { 1, 10, 1, 10 }, 1);paint.setPathEffect(effects);for (int i = 1; (y0Point - i * yScale) >= margin; i++) {int startX = x0Point;int startY = y0Point - i * yScale;int stopX = x0Point + (xLabel.length - 1) * xScale;path.moveTo(startX, startY);path.lineTo(stopX, startY);paint.setColor(Color.DKGRAY);canvas.drawPath(path, paint);}}/** * 画y轴线 *  * @param canvas * @param p */private void drawYAxis(Canvas canvas, Paint p) {// y轴.canvas.drawLine(x0Point, y0Point, margin, margin, p);// y轴箭头的左部分.canvas.drawLine(x0Point, margin, x0Point - x0Point / ARROW_PECENT,margin + margin / ARROW_PECENT, p);// y轴箭头的右部分.canvas.drawLine(x0Point, margin, x0Point + x0Point / ARROW_PECENT,margin + margin / ARROW_PECENT, p);}/** * 画x轴线. *  * @param canvas * @param p */private void drawXAxis(Canvas canvas, Paint p) {// x轴.canvas.drawLine(x0Point, y0Point, getWidth() - margin, y0Point, p);// x轴箭头的上部分.canvas.drawLine(getWidth() - margin, y0Point, getWidth() - margin- margin / ARROW_PECENT, y0Point - margin / ARROW_PECENT, p);// x轴箭头的下部分.canvas.drawLine(getWidth() - margin, y0Point, getWidth() - margin- margin / ARROW_PECENT, y0Point + margin / ARROW_PECENT, p);}// 画数据private void drawData(Canvas canvas) {Paint p = new Paint();p.setAntiAlias(true); // 抗锯齿.p.setColor(Color.RED);p.setTextSize(margin / X_TEXT_PECENT);for (int x = 0; x < data.length; x++) {int startX = x0Point + x * xScale;// 轴坐标点文字的显示.canvas.drawText(xLabel[x], startX, y0Point + xTextDistanceAxis, p);// 数据点的圆.canvas.drawCircle(startX, calY(data[x]), dataRadius, p);// 在数据点上标数据值.canvas.drawText(data[x] + "", startX, calY(data[x]) + dataRadius- dataTextAboveCircle, p);// 在数据点圆间画变化线.// 画线时,最后数据点不执行操作.if (x != data.length - 1)canvas.drawLine(startX, calY(data[x]), startX + xScale,calY(data[x + 1]), p);} // for x.// 画y轴坐标点文字.Paint py = new Paint();py.setAntiAlias(true); // 抗锯齿.py.setColor(Color.RED);py.setTextSize(margin / Y_TEXT_PECENT);for (int y = 0; y < yLabel.length; y++) {int startY = y0Point - y * yScale;// y轴坐标点文字的显示.canvas.drawText(yLabel[y], x0Point - yTextDistanceAxis, startY, py);} // for y.// 画标题.Paint pTitle = new Paint();pTitle.setAntiAlias(true); // 抗锯齿.pTitle.setColor(Color.RED);pTitle.setTextSize(margin / TITLE_TEXT_PECENT);// 通过Paint.measureText计算标题长度的像素,进而将标题水平居中.canvas.drawText(title, (getWidth() - pTitle.measureText(title)) / 2,margin - titleHeight, pTitle);}/** * 计算数据值在坐标系中y的位置. *  * @param y * @return */private int calY(int y) {int y0 = 0;int y1 = 0;try {y0 = Integer.parseInt(yLabel[0]);y1 = Integer.parseInt(yLabel[1]);return y0Point - ((y - y0) * yScale / (y1 - y0));} catch (NumberFormatException e) {Log.d("sysout", "y轴label必须是数字:" + e.getMessage());return -1;}}}

然后在Activity中调用即可:

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);//test:int[] data = { 0, 50, 51, 78, 200, 121, 31 };final String title = "最近一周AQI变化图";setContentView(new BrokenLineView(this, title, null, null, data));initView();}

更多相关文章

  1. Android右箭头的显示文字的View
  2. PHP中箭头函数的实例详解
  3. Google地图信息窗口左箭头,右箭头传递TypeError:无法读取未定义的
  4. JQuery仿最新淘宝网首页带箭头幻灯片,JQuery轮播图
  5. 如何通过多次单击在画布上显示多个箭头
  6. javaES6箭头函数的全新特性
  7. 在JComboBox箭头JButton上附加动作事件

随机推荐

  1. 属性动画
  2. Android使用Palette获取图片主色调
  3. 如何扩展Android富文本之Html标签
  4. Android核心模块及相关技术(自IT168)
  5. Android(安卓)TV框架TIF
  6. Android 上的安全性
  7. Android SDCard Filesystem
  8. Android入门之搭建Android开发环境
  9. android 隐藏API 在源码下编译报错cannot
  10. Android 多线程之 Handler 基本使用