前几天为了实现类window资源管理器的效果实现了这个折线图。
效果如下:
使用方法:
通过renderPoint添加节点。
代码如下:
package com.hyena.cpumonitor.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Point; import android.util.AttributeSet; import android.view.View; /** * 折线图 * @author yangzc * */ public class LineChartView extends View { private int mSpeedX = 4;//速度 //刻度相关 private int mScalePos = 0;//刻度面板位置 // private int mCurYMaxValue = 0; private int mScaleCellWidth = 0; private Canvas mScaleCanvas = new Canvas(); private Bitmap mScaleBitmap; private Path mScalePath; private Paint mScalePaint = new Paint(); //图表相关 private int mGraphicPos = 0; private int mSecoundGraphicPos = 0; private Canvas mGraphicCanvas = new Canvas(); private Bitmap mGraphicBitmap; private Paint mGraphicPaint = new Paint(); private Point mLastPoint = new Point(); private int mWidth = 0; private int mHeight = 0; public LineChartView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public LineChartView(Context context, AttributeSet attrs) { super(context, attrs); } public LineChartView(Context context) { super(context); } /** * 添加采样点 * @param value */ public void renderPoint(int value){ if(mGraphicPos <= -mWidth){ mGraphicPos = 0; Bitmap graphicBm = Bitmap.createBitmap(mGraphicBitmap, mWidth, 0, mWidth, mHeight); mGraphicBitmap = Bitmap.createBitmap(mWidth*2, mHeight, Bitmap.Config.ARGB_8888); mGraphicCanvas.setBitmap(mGraphicBitmap); mGraphicCanvas.drawBitmap(graphicBm, 0, 0, null); mLastPoint.x = mWidth; } float v = mHeight - (value / 100f * mHeight); mGraphicCanvas.drawLine(mLastPoint.x, mLastPoint.y, mLastPoint.x + mSpeedX, v, mGraphicPaint); mLastPoint = new Point(mLastPoint.x + mSpeedX, (int) v); invalidate(); mGraphicPos -= mSpeedX; mSecoundGraphicPos -= mSpeedX; } /** * 构筑刻度 * @param x * @param y * @param width * @param height * @param maxXValue * @param maxYValue * @return */ private Path buildScalePath(int x, int y, int width, int height, int maxXValue, int maxYValue) { Path path = new Path(); int rowHeight = Math.round(height / maxYValue)%2 == 0 ? Math.round(height / maxYValue): Math.round(height / maxYValue) + 1; int columnWidth = Math.round(width / maxXValue)%2 == 0 ? Math.round(width / maxXValue) : Math.round(width / maxXValue) + 1; //画X轴 for(int i=0; i< maxYValue; i++){ path.moveTo(x, i * rowHeight); path.lineTo(x + width, i * rowHeight); } //画竖线 for(int i=0; i< maxXValue; i++){ path.moveTo(i * columnWidth, y); path.lineTo(i * columnWidth, y + height); } path.close(); return path; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); if(w <= 0 || h <= 0)return; this.mWidth = w; this.mHeight = h; //构造刻度内容 mScaleBitmap = Bitmap.createBitmap(w + 40, h, Bitmap.Config.ARGB_8888); mScaleCanvas.setBitmap(mScaleBitmap); mScalePaint.setAntiAlias(true); mScalePaint.setColor(Color.GREEN); mScalePaint.setStrokeWidth(.5f); mScalePaint.setStyle(Paint.Style.STROKE); mScalePath = buildScalePath(0, 0, mWidth + 40, mHeight, 25, 8); mScaleCanvas.drawPath(mScalePath, mScalePaint); mScaleCellWidth = (mWidth + 40)/25; //单元格宽度务必要可以被2整除 mScaleCellWidth = mScaleCellWidth%2 == 0 ? mScaleCellWidth : mScaleCellWidth + 1; mSpeedX = mScaleCellWidth/2; //构造图表 mGraphicBitmap = Bitmap.createBitmap(w*2, h, Bitmap.Config.ARGB_8888); mGraphicCanvas.setBitmap(mGraphicBitmap); mGraphicPaint.setAntiAlias(true); mGraphicPaint.setColor(Color.GREEN); mGraphicPaint.setStyle(Paint.Style.STROKE); mGraphicPos = mWidth; mLastPoint = new Point(10, 0); if(mLineChartStateChangeListener != null) mLineChartStateChangeListener.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { int left = mScalePos - mSpeedX; // Log.v("yangzc", "Left : " +left + ", mScaleCellWidth: " + mScaleCellWidth); if(Math.abs(left) >= mScaleCellWidth) left = 0; canvas.drawBitmap(mScaleBitmap, left, 0, null); mScalePos = left; //画报表 canvas.drawBitmap(mGraphicBitmap, mGraphicPos, 0, null); } private LineChartStateChangeListener mLineChartStateChangeListener; public void setLineChartStateChangeListener(LineChartStateChangeListener lineChartStateChangeListener){ this.mLineChartStateChangeListener = lineChartStateChangeListener; } public static interface LineChartStateChangeListener { public void onSizeChanged(int w, int h, int oldw, int oldh); } }