轻松搞定Android中自定义折线图

xiaoxiao2021-02-28  158

现在很多的第三方图表虽然用起来比较方便,但感觉有时候项目中需要自己画,为了避免尴尬的状况出现.今天索性屡屡思路来个简单的折线图. 首先自定义View;

//自定义LinearSelfView public class LinearSelfView extends View { private HashMap<Double, Double> map; private int marginB;//表格x轴与屏幕底部差 private int marginLeft;//屏幕坐标原点和表格坐标原点x之差 private int totalValue;//表格的竖向高度 private int jvalue;//表格纵向间距 private boolean isShow;//横竖直线是否显示 private int bHeight;//坐标原点与屏幕坐标原点之间的高度差 private Context context; private int width;//屏幕的宽度 private int height;//屏幕的高度 private ArrayList<Double> xlk;//存放横坐标的集合 private Point[] mPoints;// private Paint paint;//画笔 private Point endPoint; private Point startPoint; private ArrayList<Integer> horizontal;//存放横坐标刻度值的集合 //自定义一个方法,从对应的Activity中传值 public void setView(Context context, int marginB, int marginLeft, int totalValue, int jvalue) { this.marginB = marginB; this.marginLeft = marginLeft; this.totalValue = totalValue; this.jvalue = jvalue; } //自定义这个方法目的是在于把map值传过来 public void setPointMap(HashMap<Double, Double> map) { this.map = map; } //复写onMeasure()方法,获取屏幕宽高 @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //获取屏幕宽 width = getMeasuredWidth(); //获取屏幕的高 height = getMeasuredHeight(); } //自定义这个方法将横坐标每个刻度数传过来 public void setHorizontal(ArrayList<Integer> horizontal) { //写一个异常抛出的方法,便于看错误日志 if(horizontal.size() != map.size()) throw new RuntimeException("传入的坐标与横坐标刻度数不符 坐标数:"+ map.size() + "刻度数: "+horizontal.size()); this.horizontal = horizontal; //刷新界面 postInvalidate(); } //复写onDrow()方法 @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); xlk = Tools.getintFormMap(map);//从小到大保存x的坐标; paint = new Paint(Paint.ANTI_ALIAS_FLAG);//不建议在onDraw方法里new paint.setStrokeWidth(2); paint.setStyle(Paint.Style.STROKE);//实心 paint.setColor(Color.WHITE); bHeight = height - marginB;//算出bHeight的值 int jSize = totalValue / jvalue;//算出y轴总共有的格子数(单元格数); for (int i = 0; i < jSize + 1; i++) { //画出与x轴平行的几条线(横线) canvas.drawLine(marginLeft, bHeight - bHeight / jSize * i, width, bHeight - bHeight / jSize * i, paint); //画出y轴的刻度 canvas.drawText(String.valueOf(jvalue * i), marginLeft / 2, bHeight - bHeight / jSize * i, paint); } //自定义一个数组将放入轴的各个刻度值 ArrayList<Integer> xList = new ArrayList<>(); for (int i = 0; i < xlk.size(); i++) { xList.add(marginLeft + (width - marginLeft) / xlk.size() * i); int a = marginLeft + (width - marginLeft) / xlk.size() * i; Log.d("LinearSelfView", "a:" + a); float startX = marginLeft + (width - marginLeft) / horizontal.size() * i; float stopX = marginLeft + (width - marginLeft) / horizontal.size() * i;//x刻度 float stopY = bHeight; //与y轴平行的线(竖线) canvas.drawLine(startX, 0, stopX, stopY, paint); canvas.drawText(String.valueOf(horizontal.get(i)), marginLeft + (width - marginLeft) / horizontal.size() * i, bHeight + 10, paint); } mPoints = getPoints(xList); //连线 paint.setColor(ContextCompat.getColor(getContext(), R.color.colorLine)); drawLine(mPoints, canvas, paint); //画点 paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); for (int j = 0; j < mPoints.length; j++) { canvas.drawRect(pointRect(mPoints[j]), paint); } } //画的小方块(坐标点的周围) int RECT_SIZE = 3; //对点的左右进行运算 private RectF pointRect(Point Point) { return new RectF(Point.x - RECT_SIZE, Point.y - RECT_SIZE, Point.x + RECT_SIZE, Point.y + RECT_SIZE); } private void drawLine(Point[] mPoints2, Canvas canvas, Paint paint) { //利用相邻的俩个点进行连线 startPoint = new Point(); endPoint = new Point(); for (int i = 0; i < mPoints2.length - 1; i++) { startPoint = mPoints2[i]; endPoint = mPoints2[i + 1]; //利用所有点的横纵坐标进行连线 canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint); } } //TODO 随着传入的map值的多少不一样 ,需要改变横坐标的个数 private Point[] getPoints(ArrayList<Integer> xList) { //得到点的数组(横纵坐标) Point[] points = new Point[xList.size()]; for (int i = 0; i < points.length; i++) { int py = (int) (bHeight - (bHeight * (map.get(xlk.get(i)) / totalValue)));//y的坐标 points[i] = new Point(xList.get(i), py); } return points; } } Activity里的只需要将map的值和自定义方法传入即可
转载请注明原文地址: https://www.6miu.com/read-32207.html

最新回复(0)