package com.swj.copd.view;
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.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class LineView extends View {
private static final String TAG = "LineView";
// private int[] yLables = {1, 6, 11, 16, 21,1, 6, 11, 16, 21,1}; //固定y轴数字
private Context mContext;
private List<String> xValues = new ArrayList<>();
private List<Float> yValues = new ArrayList<>();
private List<String> yLables = new ArrayList<>();
private int mWidth;
private int mHeight;
private int originX; // 原点x坐标
private int originY; // 原点y坐标
private int intervalX = 130; // 坐标刻度的间隔
private int intervalY = 80; // y轴刻度的间隔
private int paddingTop = 140;// 默认上下左右的padding
private int paddingLeft = dip2px(80);
private int paddingRight = dip2px(30);
private int paddingBottom = 150;
private int firstPointX; //第一个点x坐标
private int xScaleHeight = dip2px(6); // x轴刻度线高度
private int xyTextSize = sp2px(10); //xy轴文字大小
private int textToXYAxisGap = dip2px(10); // xy轴的文字距xy线的距离
private int lableCountY; // Y轴刻度个数
private int leftRightExtra = intervalX / 3; //x轴左右向外延伸的长度
private float minValueY = 1; // y轴最小值
private float maxValueY = 26; // y轴最大值
private int bigCircleR = 7; //折线图中的圆圈
private int smallCircleR = 5; //折线图中为了避免折线穿透的圆圈
private GestureDetector gestureDetector; //滑动手势
private int firstMinX; // 移动时第一个点的最小x值
private int firstMaxX; //移动时第一个点的最大x值
private int backGroundColor = Color.parseColor("#272727"); // view的背景颜色
private Paint paintWhite, paintBlue, paintRed, paintBack, paintText, dashPaint;
private void initPaint()
{
paintWhite = new Paint(Paint.ANTI_ALIAS_FLAG);
paintWhite.setColor(Color.WHITE);
paintWhite.setStyle(Paint.Style.STROKE);
paintBlue = new Paint(Paint.ANTI_ALIAS_FLAG);
paintBlue.setColor(Color.parseColor("#0198cd"));
paintBlue.setStrokeWidth(3f);
paintBlue.setStyle(Paint.Style.STROKE);
paintBack = new Paint(Paint.ANTI_ALIAS_FLAG);
paintBack.setColor(Color.parseColor("#272727"));
paintBack.setStyle(Paint.Style.FILL);
paintRed = new Paint(Paint.ANTI_ALIAS_FLAG);
paintRed.setColor(Color.RED);
paintRed.setStrokeWidth(3f);
paintRed.setStyle(Paint.Style.STROKE);
paintText = new Paint(Paint.ANTI_ALIAS_FLAG);
paintText.setColor(Color.WHITE);
paintText.setTextSize(xyTextSize);
paintText.setStrokeWidth(2f);
dashPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
dashPaint.setColor(Color.WHITE);
dashPaint.setStyle(Paint.Style.STROKE);
dashPaint.setStrokeWidth(1f);
}
public LineView(Context context) {
this(context, null);
}
public LineView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public LineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
initPaint();
gestureDetector = new GestureDetector(context, new MyOnGestureListener());
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (changed) {
mWidth = getWidth();
mHeight = getHeight();
originX = paddingLeft - leftRightExtra;
originY = mHeight - paddingBottom;
firstPointX = paddingLeft;
firstMinX = mWidth - originX - (xValues.size() - 1) * intervalX - leftRightExtra;
// 滑动时,第一个点x值最大为paddingLeft,在大于这个值就不能滑动了
firstMaxX = firstPointX;
setBackgroundColor(backGroundColor);
}
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onDraw(Canvas canvas) {
drawX(canvas);
if(yLables.size() != 0 && yValues.size() != 0)
drawLine(canvas);
drawY(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec),measureHeight(heightMeasureSpec));
}
private int measureHeight(int measureSpec)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if(specMode == MeasureSpec.EXACTLY)
{
result = specSize;
}
else
{
result = yLables.size()*100+100;
if(specMode == MeasureSpec.AT_MOST)
{
result = Math.min(result,specSize);
Log.e(TAG, "measureHeight: "+result );
}
}
return result;
}
private void drawX(Canvas canvas)
{
Path path = new Path();
path.moveTo(originX,originY);
// x 轴线
path.lineTo(mWidth - paddingRight,originY);
canvas.drawPath(path, paintWhite);
// x轴箭头
canvas.drawLine(mWidth - paddingRight, originY, mWidth - paddingRight - 15, originY + 10, paintWhite);
canvas.drawLine(mWidth - paddingRight, originY, mWidth - paddingRight - 15, originY - 10, paintWhite);
for (int i = 0; i < xValues.size(); i++) {
// x轴线上的刻度线
canvas.drawLine(firstPointX + i * intervalX, originY, firstPointX + i * intervalX, originY - xScaleHeight, paintWhite);
// x轴上的文字
canvas.drawText(xValues.get(i), firstPointX + i * intervalX - getTextWidth(paintText, "17.01") / 2,
originY + dip2px(20), paintText);
}
// x轴虚线
Path path1 = new Path();
DashPathEffect dash = new DashPathEffect(new float[]{8, 10, 8, 10}, 0);
dashPaint.setPathEffect(dash);
for (int i = 0; i < lableCountY; i++) {
path1.moveTo(originX, mHeight - paddingBottom - leftRightExtra - i * intervalY);
path1.lineTo(mWidth - paddingRight, mHeight - paddingBottom - leftRightExtra - i * intervalY);
}
canvas.drawPath(path1, dashPaint);
}
/**
* 画y轴
*
* @param canvas
*/
private void drawY(Canvas canvas) {
// canvas.save();
Path path = new Path();
path.moveTo(originX, originY);
for (int i = 0; i < lableCountY; i++) {
// y轴线
path.lineTo(originX, mHeight - paddingBottom - leftRightExtra - i * intervalY);
}
canvas.drawPath(path, paintWhite);
//y轴最后一个刻度的位置
int lastPointY = mHeight - paddingBottom - leftRightExtra - (lableCountY - 1) * intervalY;
// 箭头位置,y轴最后一个点后,需要额外加上一小段,就是一个半leftRightExtra的长度
int lastY = lastPointY - leftRightExtra - leftRightExtra / 2;
// y轴箭头
评论0