效果图:
代码实现:
package com.jiahao.me; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.os.Bundle; public class MainActivity extends Activity { private ChartView chartView; ArrayList<Double> yList; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); chartView = (ChartView) findViewById(R.id.chartView); // yList = new ArrayList<Double>(); // yList.add((double) 2.103); // yList.add(4.05); // yList.add(6.60); // yList.add(3.08); // yList.add(4.32); // yList.add(2.0); // yList.add(5.0); // // ArrayList<String> xRawDatas = new ArrayList<String>(); // xRawDatas.add("05-19"); // xRawDatas.add("05-20"); // xRawDatas.add("05-21"); // xRawDatas.add("05-22"); // xRawDatas.add("05-23"); // xRawDatas.add("05-24"); // xRawDatas.add("05-25"); // xRawDatas.add("05-26"); // // xRawDatas.add("05-19"); // xRawDatas.add("05-20"); // xRawDatas.add("05-21"); // xRawDatas.add("05-22"); // xRawDatas.add("05-23"); // xRawDatas.add("05-24"); // xRawDatas.add("05-25"); // xRawDatas.add("05-26"); // // xRawDatas.add("05-19"); // xRawDatas.add("05-20"); // xRawDatas.add("05-21"); // xRawDatas.add("05-22"); // xRawDatas.add("05-23"); // xRawDatas.add("05-24"); // xRawDatas.add("05-25"); // xRawDatas.add("05-26"); // chartView.setData(yList, xRawDatas, 8, 2); List<Float> values = new ArrayList<Float>(); List<String> xlabel = new ArrayList<String>(); values.add(36.5f); xlabel.add("02-01"); values.add(35.5f); xlabel.add("02-02"); values.add(34.3f); xlabel.add("02-03"); values.add(36.8f); xlabel.add("02-04"); values.add(36.4f); xlabel.add("02-05"); values.add(37.1f); xlabel.add("02-06"); values.add(37.5f); xlabel.add("02-07"); values.add(36.5f); xlabel.add("02-08"); values.add(36.2f); xlabel.add("02-09"); values.add(38.5f); xlabel.add("02-10"); values.add(36.5f); xlabel.add("02-11"); values.add(37.1f); xlabel.add("02-06"); values.add(37.5f); xlabel.add("02-07"); values.add(36.5f); xlabel.add("02-08"); values.add(36.2f); xlabel.add("02-09"); values.add(38.5f); xlabel.add("02-10"); values.add(36.5f); xlabel.add("02-11"); values.add(37.1f); xlabel.add("02-12"); values.add(37.5f); xlabel.add("02-13"); values.add(36.5f); xlabel.add("02-14"); /**values.add(36.2f); xlabel.add("02-15"); values.add(38.5f); xlabel.add("02-15"); values.add(36.5f); xlabel.add("02-17"); values.add(37.1f); xlabel.add("02-08"); values.add(37.5f); xlabel.add("02-09"); values.add(36.5f); xlabel.add("02-20"); values.add(36.2f); xlabel.add("02-21"); values.add(38.5f); xlabel.add("02-22"); values.add(36.5f); xlabel.add("02-23"); **/ chartView.setValueData(values, xlabel); } }
package com.jiahao.me; import java.util.List; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.PaintFlagsDrawFilter; import android.graphics.PathEffect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.renderscript.Element; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.view.WindowManager; @SuppressLint("NewApi") public class ChartView extends View { private Paint paint; private int marginTop = 70; private int yLabelHeihgt = 70; private int marginBottom = 10; private int widthScreen; private DisplayMetrics dm; private WindowManager windowManager; private List<Float> values; private List<String> xlabel; private float radius = 5f; private float minValue = 34f; private float maxValue = 39f; private float marginLeft = 20; // Y轴文字的宽度 private float labelWidth = 40f; private float xLabelWidth =70f; private Paint circlePaint; private String [] yVal; private Paint xuLinePaint; private Bitmap water; private Bitmap heart; private int lastX; private int lastY; private int initLeft; private int parentWidth; private int offX; private int offY; private int scrollX; private int scrollY; private int downLeft; private int downRight; private float pointX; public ChartView(Context context, AttributeSet attrs) { super(context, attrs); windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); widthScreen = windowManager.getDefaultDisplay().getWidth(); water = BitmapFactory.decodeResource(context.getResources(), R.drawable.water); heart = BitmapFactory.decodeResource(context.getResources(), R.drawable.heart); } @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setAntiAlias(false); paint.setTextSize(12); paint.setColor(Color.BLACK); circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG); circlePaint.setAntiAlias(false); circlePaint.setColor(Color.parseColor("#fc5a9c")); xuLinePaint = new Paint(); xuLinePaint.setAntiAlias(false); xuLinePaint.setStyle(Paint.Style.STROKE); xuLinePaint.setColor(Color.parseColor("#fc5a9c")); PathEffect effects = new DashPathEffect(new float[]{5,5,5,5},1); xuLinePaint.setPathEffect(effects); canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); // 画默认图表 initViews(canvas); initLeft = getLeft(); Log.e("Test", "initLeft=" + initLeft); drawValues(canvas); } public void setValueData(List<Float> values,List<String> xlabel) { this.xlabel = xlabel; this.values = values; } private void initViews(Canvas canvas) { yVal = new String []{"39.0","38.5","38.0","37.5","37.0","36.5","36.0","35.5","35.0","34.5","34.0"}; pointX = 0f; if (values != null && values.size() > 0) { pointX = (yLabelHeihgt * (values.size() + 1)) + labelWidth * 2; } // for (int i = 0;i < values.size();i++) { // pointX = pointX + (yLabelHeihgt * (i + 1)) + (labelWidth / 2); // } for (int i = 0; i < yVal.length;i++) { // canvas.drawText(yVal[i], labelWidth, (yLabelHeihgt * (i + 1)), paint); if (pointX > widthScreen) { canvas.drawLine(0, (yLabelHeihgt * (i + 1)), pointX, (yLabelHeihgt * (i + 1)), paint); } else { // labelWidth + 40 canvas.drawLine(0, (yLabelHeihgt * (i + 1)), widthScreen, (yLabelHeihgt * (i + 1)), paint); } } if (pointX > widthScreen) { ViewGroup viewGroup = (ViewGroup) getParent(); if (viewGroup != null) { LayoutParams params = viewGroup.getLayoutParams(); params.width = (int)pointX; viewGroup.setLayoutParams(params); parentWidth = (int)pointX; } } } private void drawValues(Canvas canvas) { // 画 点和线 if (values != null && values.size() > 0) { float initPointX = 0f; float initPointY = 0f; float pointX = 0f; float pointY = 0f; for (int i = 0;i < values.size();i++) { float f = values.get(i); if (f <= minValue) { pointX = (((i + 1) * xLabelWidth)); pointY = (yLabelHeihgt * (i + 1)); if (initPointX > 0) { canvas.drawLine(initPointX, initPointY, pointX, pointY, circlePaint); } canvas.drawCircle(pointX, pointY, radius, circlePaint); initPointX = pointX; initPointY = pointY; } else if (f >= maxValue) { pointX = (((i + 1) *xLabelWidth)); pointY = yLabelHeihgt; if (initPointX > 0) { canvas.drawLine(initPointX, initPointY, pointX, pointY, circlePaint); } canvas.drawCircle(pointX, pointY, radius, circlePaint); initPointX = (labelWidth * (i + 1)); initPointY = yLabelHeihgt; } else { float pxheight = (maxValue - minValue) / (yLabelHeihgt * (i + 1)); // Log.e("Test", "pxheight=" + pxheight); pointY = (float)((((maxValue - f ) / 0.5) + 1) * yLabelHeihgt); pointX = (yLabelHeihgt * (i + 1)) + (labelWidth / 2); if (initPointX > 0) { canvas.drawLine(initPointX, initPointY, pointX, pointY, xuLinePaint); } initPointX = pointX; initPointY = pointY; canvas.drawCircle(pointX, pointY, radius, circlePaint); } // 下面绘制 canvas.drawBitmap(water, (pointX - (water.getWidth() / 2)), (pointY + (water.getHeight() / 2)), circlePaint); // 上面绘制 canvas.drawBitmap(heart, (pointX - (heart.getWidth() / 2)), (pointY - (heart.getHeight() + heart.getHeight() / 2)), circlePaint); } } // 画 X轴 label if (xlabel != null && xlabel.size() > 0) { for (int i = 0;i < xlabel.size();i++) { float pointY = (yLabelHeihgt * yVal.length) + 15; float pointX = (yLabelHeihgt * (i + 1)); canvas.drawText(xlabel.get(i) + "", pointX, pointY, paint); } } ViewGroup viewGroup = (ViewGroup) getParent(); if (viewGroup != null) { Log.e("Test", "parent width=" + viewGroup.getLayoutParams().width); } } @Override public boolean onTouchEvent(MotionEvent event) { int x = (int)event.getX(); int y = (int)event.getY(); boolean flag = true; if (event.getAction() == MotionEvent.ACTION_DOWN) { lastX = x; lastY = y; downLeft = getLeft(); downRight = getRight(); } else if (event.getAction() == MotionEvent.ACTION_MOVE) { // 计算移动的距离 offX = x - lastX; offY = y - lastY; if (x > lastX) { // 向左滚动 Log.e("Test22", "向右边滚动........."); // if (getRight() > widthScreen - xLabelWidth) { // layout(getLeft() + offX, getTop(), getRight() + offX, getBottom()); // } } else { // 向右边滚动 Log.e("Test22", "向左滚动........."); // if (getLeft() < 0) { // layout(getLeft() + offX, getTop(), getRight() + offX, getBottom()); // } } // 调用layout重新绘制 // if (getLeft() >= 0) { // layout(getLeft() + offX, getTop(), getRight() + offX, getBottom()); // } // Log.e("Test22", "left:" + getLeft()); // Log.e("Test22", "right:" + getRight()); // // // // Log.e("Test", "getLeft() + parentWidth=" + (getLeft() + parentWidth)); // Log.e("Test", "widthScreen=" + widthScreen); if (((getLeft() + parentWidth) >= widthScreen && getLeft() <= 0)) { // Log.e("Test", "执行了onLayout"); layout(getLeft() + offX, getTop(), getRight() + offX, getBottom()); Log.e("Test", "进来了"); } else { Log.e("Test", "没有进来"); if (x > lastX && getLeft() <=0) { layout(getLeft() + offX, getTop(), getRight() + offX, getBottom()); } // else { // if (getLeft() > 0) { // layout(getLeft(), getTop(), getRight(), getBottom()); // } // } // if (getLeft() > 0) { // setLeft(0); // } else if ((getLeft() + parentWidth) < widthScreen){ // setLeft(widthScreen); // } // scrollX = getLeft(); // scrollY = getRight(); // Log.e("Test", "未执行......"); // // layout(getLeft(), getTop(), getRight() + offX, getBottom()); } Log.e("Test", "left:" + getLeft()); Log.e("Test", "right:" + getRight()); } else if (event.getAction() == MotionEvent.ACTION_UP) { if (getLeft() > 0) { Log.e("Test", "=====================11============"); setLeft(0); layout(getLeft(), getTop(), getRight(), getBottom()); } else if (getRight() < widthScreen) { // layout(parentWidth - getRight(), getTop(), parentWidth - getLeft(), getBottom()); Log.e("Test", "=======================12==========downRight=" + downRight); Log.e("Test", "=======================12==========parentWidth=" + parentWidth); Log.e("Test", "=======================12==========downLeft=" + downLeft); // setRight(widthScreen - 5); // layout(getRight() - parentWidth, getTop(), getRight(), getBottom()); // setLeft(widthScreen - parentWidth); // setRight(parentWidth - Math.abs(getLeft())); // layout(downLeft, getTop(), downRight, getBottom()); // setRight(widthScreen); // setLeft(Math.abs(downLeft) - parentWidth); Log.e("Test", "=======================12==========left=" + (Math.abs(downLeft) - parentWidth)); Log.e("Test", "=======================12==========right=" + widthScreen); // layout(Math.abs(downLeft) - parentWidth, getTop(), widthScreen, getBottom()); } // else if (((getLeft() + parentWidth) < widthScreen)) { // setLeft(scrollX); // setRight(scrollY); // layout(scrollX- 1, getTop(), scrollY -1, getBottom()); // } // Log.e("Test22", "ACTION_UP==========="); // // Log.e("Test22", "getLeft:" + getLeft()); // Log.e("Test22", "getRight:" + getRight()); } return flag; } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { Log.e("Test", "widthMeasureSpec=" + widthMeasureSpec); Log.e("Test", "heightMeasureSpec=" + heightMeasureSpec); super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }