MPAndroidChart 的实现

效果图:

代码实现:

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

}
原文地址:https://www.cnblogs.com/jiayonghua/p/5257094.html