对自定义折线图 曲线图进行 图层优化后的代码,之前的性能差效果不友好,修改为:类似支付宝 中查看基金走势图的效果

package com.zz.kotlintest.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;

import com.zz.kotlintest.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author xifangzheng
 * Created by zz on 2017/9/13 17:32.
 *   class explain:     曲线、折线  统计图
 *     update:       upAuthor:      explain:
 */

public class LineGraphicView extends View {

    String LogTag = this.getClass().getSimpleName();
    /**
     * 公共部分
     */
    private static final int CIRCLE_SIZE = 6;   // 圆点的直径
    private boolean isDrawCirclePoints = true;  //是否画每个圆点
    public ArrayList<ArrayList<Double>> yRawDataLineList; // TODO 自己新增 线的集合
    private ArrayList<Paint> paintList;
    public float pointSpace;   // 两个点之间的 x 轴间距
    public ArrayList<String> showAlertTextList;
    public ArrayList<Boolean> isShowBottomRawDatas;
    public ArrayList<Boolean> isShowTopTextIndexList;
    private boolean clearView;
    private String clearAfterShowText = "暂无数据";


    public static enum Linestyle {
        Line,   //折线
        Curve;  //曲线
    }

    private Context mContext;

    private Paint mPaint;
    private Resources res;
    private DisplayMetrics dm;
    /**
     * data
     */
    private Linestyle mStyle = Linestyle.Line;

    public void setStyle(Linestyle mStyle) {
        this.mStyle = mStyle;
    }

    private int canvasHeight;

    public int canvasWidth;
    public int bheight = 0;    // 表的高度
    private int bwidth = 0;     // 表的宽度
    private int blwidh;         // 表的左右边距
    private boolean isMeasure = true;
    /**
     * Y轴最大值
     */
    private float maxValue;
    /**
     * Y轴间距值
     */
    private float averageValue;
    public int marginTop = 40;
    private int marginBottom = 20;

    int bottomTextVerticalSpacing = 4;
    int bottomTextHeight = 24;  // 这个可让画布增加底部文字的高度

    /**
     * 曲线上总点数
     */
    private Point[] mPoints;
    public ArrayList<Point[]> mPointsLineList;    // TODO 新增用来存放所有线的点的集合
    /**
     * 纵坐标值
     */
    private ArrayList<Double> yRawData;
    /**
     * 横坐标值
     */
    public ArrayList<String> xRawDatas; // 底部显示的文字
    private ArrayList<Integer> xList = new ArrayList<Integer>();// 记录每个x的值
    private ArrayList<ArrayList<Float>> xListLineList = new ArrayList<>();// 记录每个x的值 // TODO 新增
    private float spacingHeight;

    public boolean isDrawCirclePoints() {
        return isDrawCirclePoints;
    }

    public void setDrawCirclePoints(boolean drawCirclePoints) {
        isDrawCirclePoints = drawCirclePoints;
    }

    public LineGraphicView(Context context) {
        this(context, null);
    }

    public LineGraphicView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initView();
    }

    private void initView() {
        this.res = mContext.getResources();
        this.mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setAntiAlias(true);
        dm = new DisplayMetrics();
        WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        wm.getDefaultDisplay().getMetrics(dm);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e(LogTag,"onMeasure");
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        Log.e(LogTag,"onFinishInflate");
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        Log.e(LogTag,"onLayout");
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        Log.e(LogTag,"onSizeChanged");
        if (isMeasure) {
//            this.canvasHeight = getHeight();   // 高度
            this.canvasHeight = getHeight() - dip2px(bottomTextHeight) - dip2px(bottomTextVerticalSpacing);   //  减的bottomTextHeight是文字的高度
            this.canvasWidth = getWidth();
            if (bheight == 0) {
                bheight = (int) (canvasHeight - marginBottom);
            }
            blwidh = dip2px(19);
            this.bwidth = canvasWidth - blwidh * 2;
            isMeasure = false;
//            pointSpace = (canvasWidth - blwidh * 2) / (xRawDatas.size() - 1);
        }
        if (xRawDatas == null) {
            return;
        }
        pointSpace = Float.valueOf(canvasWidth - blwidh * 2) / (xRawDatas.size() - 1);
//        Log.e("onSizeChanged打印:", "pointSpace:" + pointSpace + "  canvasWidth:" + canvasWidth + "  blwidh:" + blwidh + " bwidth:" + bwidth);
    }

    @Override
    public void onDrawForeground(Canvas canvas) {
        super.onDrawForeground(canvas);
        Log.e(LogTag,"onDrawForeground");
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.e(LogTag,"onDraw");
        if (clearView) {
            mPaint.setColor(res.getColor(R.color.color_DefaultDrawLine));
            mPaint.setStrokeWidth(dip2px(0));
            mPaint.setTextSize(dip2px(15));
            mPaint.setStyle(Paint.Style.STROKE);
            mPaint.setFlags(Gravity.CENTER_HORIZONTAL);
            canvas.drawText(clearAfterShowText, bwidth / 2 + blwidh - 2 * mPaint.getTextSize(), bheight / 2, mPaint);
            return;
        }

        mPaint.setColor(res.getColor(R.color.color_DefaultDrawLine));
        mPaint.setStrokeWidth(dip2px(1));
        mPaint.setStyle(Paint.Style.STROKE);

        if (yRawDataLineList == null) {
            return;
        }

        drawAllXLine(canvas);
        // 画直线(纵向)
//        drawAllYLine(canvas);
        drawAllYLineList(canvas);

        // 点的操作设置
//        mPoints = getPoints();
        // 新增
        mPointsLineList = getPointsLineList();


//        mPaint.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0));
        if (mStyle == Linestyle.Curve) {
//            drawScrollLine(canvas);
            drawScrollLineList(canvas);
        } else {
//            drawLine(canvas);
            drawLineList(canvas);
        }

        mPaint.setStyle(Paint.Style.FILL);

        if (isDrawCirclePoints) {
            drawCirclePoints(canvas);
        }

    }

    public ArrayList<String> showAlertTextValuesList = new ArrayList<>();

    boolean isShowVerticalLine; // 是否展示触摸后的竖线
    boolean isShowCoverRound; // 是否展示覆盖框

    private void drawCirclePoints(Canvas canvas) {
        for (int i = 0; i < mPointsLineList.size(); i++) {
            for (int j = 0; j < mPointsLineList.get(i).length; j++) {
                if (paintList.size() == mPointsLineList.size()) {
                    canvas.drawCircle(mPointsLineList.get(i)[j].x, mPointsLineList.get(i)[j].y, CIRCLE_SIZE / 2, paintList.get(i));
                } else {
                    canvas.drawCircle(mPointsLineList.get(i)[j].x, mPointsLineList.get(i)[j].y, CIRCLE_SIZE / 2, mPaint);
                }
            }
        }
    }

    /**
     * 画所有横向表格,包括X轴
     */
    private void drawAllXLine(Canvas canvas) {
        for (int i = 0; i < spacingHeight + 1; i++) {
            if (i != 0) {
                mPaint.setColor(res.getColor(R.color.color_99XLine));
                mPaint.setStrokeWidth(2);
            } else {
                mPaint.setColor(res.getColor(R.color.color_XLine));
                mPaint.setStrokeWidth(dip2px(1));
            }
            canvas.drawLine(blwidh, bheight - (Float.valueOf(bheight) / spacingHeight) * i + marginTop,
                    (canvasWidth - blwidh),
                    bheight - (Float.valueOf(bheight) / spacingHeight) * i + marginTop, mPaint);// Y坐标
            drawText(String.valueOf(averageValue * i), blwidh / 2, bheight - (Float.valueOf(bheight) / spacingHeight) * i + marginTop,
                    canvas, R.color.color_LeftText, false);
        }
    }

    /**
     * 画所有纵向表格,包括Y轴
     */
    private void drawAllYLineList(Canvas canvas) {
        xListLineList.clear();
        for (int i = 0; i < yRawDataLineList.size(); i++) {
            ArrayList<Float> xListItem = new ArrayList<>();

            for (int j = 0; j < xRawDatas.size(); j++) {
                mPaint.setColor(res.getColor(R.color.color_YLine));
//                Log.e("xlistitem:", "" + (blwidh + (bwidth) / (xRawDatas.size() - 1) * j));
//                Log.e("drawAllYLineList打印:", "pointSpace:" + pointSpace + "  canvasWidth:" + canvasWidth + "  blwidh:" + blwidh + " bwidth:" + bwidth);
                xListItem.add(blwidh + (Float.valueOf(bwidth)) / (xRawDatas.size() - 1) * j);
                canvas.drawLine(blwidh + (Float.valueOf(bwidth)) / (xRawDatas.size() - 1) * j, marginTop,
                        blwidh + (Float.valueOf(bwidth)) / (xRawDatas.size() - 1) * j, bheight + marginTop, mPaint);
//                Log.e("画文本:", xRawDatas.get(j) + "bheight:" + bheight + "canvasWidth:" + canvasWidth);
                if (i == 0) {
                    drawText(isShowBottomRawDatas.get(j) ? xRawDatas.get(j) : "",
                            blwidh + (Float.valueOf(bwidth)) / (xRawDatas.size() - 1) * j,
                            bheight + dip2px(bottomTextHeight) + dip2px(bottomTextVerticalSpacing),
                            canvas, R.color.color_BottomText, true);// X坐标
                }
            }
            xListLineList.add(xListItem);
        }

    }

    private void drawScrollLine(Canvas canvas) {
        Point startp = new Point();
        Point endp = new Point();
        for (int i = 0; i < mPoints.length - 1; i++) {
            startp = mPoints[i];
            endp = mPoints[i + 1];
            int wt = (startp.x + endp.x) / 2;
            Point p3 = new Point();
            Point p4 = new Point();
            p3.y = startp.y;
            p3.x = wt;
            p4.y = endp.y;
            p4.x = wt;

            Path path = new Path();
            path.moveTo(startp.x, startp.y);
            path.cubicTo(p3.x, p3.y, p4.x, p4.y, endp.x, endp.y);
            canvas.drawPath(path, mPaint);
        }
    }

    Map<Integer, Integer> linesStartIndexMap = new HashMap<>();
    Map<Integer, Integer> linesEndIndexMap = new HashMap<>();

    private void drawScrollLineList(Canvas canvas) {
        linesStartIndexMap.clear();
        linesEndIndexMap.clear();
        for (int i = 0; i < mPointsLineList.size(); i++) {
            Point startp = new Point();
            Point endp = new Point();
            for (int j = 0; j < mPointsLineList.get(i).length - 1; j++) {
                startp = mPointsLineList.get(i)[j];
                endp = mPointsLineList.get(i)[j + 1];
                if (j == 0 && startp.y >= 0) {
                    linesStartIndexMap.put(i, j);
                }
                if (startp.y < 0) {
                    linesStartIndexMap.put(i, j + 1);
                    continue;
                }
                linesEndIndexMap.put(i, j + 1);
                int wt = (startp.x + endp.x) / 2;
                Point p3 = new Point();
                Point p4 = new Point();
                p3.y = startp.y;
                p3.x = wt;
                p4.y = endp.y;
                p4.x = wt;

                Path path = new Path();
                path.moveTo(startp.x, startp.y);
                path.cubicTo(p3.x, p3.y, p4.x, p4.y, endp.x, endp.y);
                if (paintList.size() == mPointsLineList.size()) {
                    canvas.drawPath(path, paintList.get(i));
                } else {
                    canvas.drawPath(path, mPaint);
                }
            }
        }
    }

    private void drawLine(Canvas canvas) {
        Point startp = new Point();
        Point endp = new Point();
        for (int i = 0; i < mPoints.length - 1; i++) {
            startp = mPoints[i];
            endp = mPoints[i + 1];
            canvas.drawLine(startp.x, startp.y, endp.x, endp.y, mPaint);
        }
    }

    private void drawLineList(Canvas canvas) {
        linesStartIndexMap.clear();
        linesEndIndexMap.clear();
        for (int i = 0; i < mPointsLineList.size(); i++) {
            Point startp = new Point();
            Point endp = new Point();
            for (int j = 0; j < mPointsLineList.get(i).length - 1; j++) {
                startp = mPointsLineList.get(i)[j];
                endp = mPointsLineList.get(i)[j + 1];
                if (j == 0 && startp.y >= 0) {
                    linesStartIndexMap.put(i, j);
                }
                if (startp.y < 0) {
                    linesStartIndexMap.put(i, j + 1);
                    continue;
                }
                linesEndIndexMap.put(i, j + 1);
                if (paintList.size() == mPointsLineList.size()) {
                    canvas.drawLine(startp.x, startp.y, endp.x, endp.y, paintList.get(i));
                } else {
                    canvas.drawLine(startp.x, startp.y, endp.x, endp.y, mPaint);
                }
            }
        }

    }

    private void drawText(String text, float x, float y, Canvas canvas, int colorRes, boolean isVerticalText) {
        drawText(text, x, y, canvas, colorRes, isVerticalText, 12);
    }

    private void drawText(String text, float x, float y, Canvas canvas, int colorRes, boolean isVerticalText, int textSizedp) {
        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
        p.setTextSize(dip2px(textSizedp));
        p.setColor(res.getColor(colorRes));
        if (isVerticalText) {
            p.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(text, x, y, p);
        } else {
            p.setTextAlign(Paint.Align.CENTER);
            canvas.drawText(text, x, y + Float.valueOf(p.getTextSize()) / 3, p);
        }
    }

    private Point[] getPoints() {
        Point[] points = new Point[yRawData.size()];
        for (int i = 0; i < yRawData.size(); i++) {
            int ph = bheight - (int) (bheight * (yRawData.get(i) / maxValue));

            points[i] = new Point(xList.get(i), ph + marginTop);
        }
        return points;
    }

    public int minTouchXPoint; // 有效触摸点 x轴坐标   起点
    public int maxTouchXPoint; // 有效触摸点 x轴坐标   终点
    // TODO 下面这个是 获得所有点的方法

    /**
     * 现在需要得到 有效的 x 轴起点和终点
     * 在这个方法中计算可得到
     * <p>
     * 目前两条线的起点都为  从0 开始有值时 正常
     * 目前其中一条线的起点为  从0 开始有值时 正常
     * <p>
     * 需要处理的是 两条线的起点为  从0 都开始 无值时 603行会报错,因为 startXPointList 集合中无值  因为取值增加目前写的是 每条线 取角标为0(第一个)的加入
     */
    private ArrayList<Point[]> getPointsLineList() {
        startTempList.clear();
        endTempList.clear();
        ArrayList<Point[]> allPointsLineList = new ArrayList<>();
        ArrayList<Integer> startXPointList = new ArrayList<>();
        ArrayList<Integer> endXPointList = new ArrayList<>();
        for (int i = 0; i < yRawDataLineList.size(); i++) {
            Point[] points = new Point[yRawDataLineList.get(i).size()];
            for (int j = 0; j < yRawDataLineList.get(i).size(); j++) {
                if (yRawDataLineList.get(i).get(j) < 0) {
                    // 为无效点  将不在画线范围  无效点 Y 轴给 -1 值  用于触摸显示 上面方框中的取值
                    points[j] = new Point(Math.round(xListLineList.get(i).get(j)), -1);
                } else {
                    int ph = bheight - (int) (bheight * (yRawDataLineList.get(i).get(j) / maxValue));
//                    Log.e("点坐标:", "x:" + xListLineList.get(i).get(j) + "    y:" + ph + marginTop);
                    points[j] = new Point(Math.round(xListLineList.get(i).get(j)), ph + marginTop);
                    a:
                    for (int k = 0; k < yRawDataLineList.get(i).size(); k++) {
                        if (yRawDataLineList.get(i).get(k) >= 0) {
                            startXPointList.add(Math.round(xListLineList.get(i).get(k)));
                            startTempList.put(k, Math.round(xListLineList.get(i).get(k)));
                            break a;
                        }
                    }

                    if (j == yRawDataLineList.get(i).size() - 1) {
                        endXPointList.add(Math.round(xListLineList.get(i).get(j)));
                        endTempList.put(j, Math.round(xListLineList.get(i).get(j)));
                    }
                }


            }
            allPointsLineList.add(points);
        }
        minTouchXPoint = Collections.min(startXPointList);
        maxTouchXPoint = Collections.max(endXPointList);
        return allPointsLineList;
    }

    Map<Integer, Integer> startTempList = new HashMap<>();
    Map<Integer, Integer> endTempList = new HashMap<>();


    public void setData(ArrayList<ArrayList<Double>> yRawData, ArrayList<String> xBottomRawData,
                        ArrayList<Boolean> isShowBottomRawDatas, ArrayList<Boolean> isShowTopTextIndexList,
                        float maxValue, float averageValue,
                        ArrayList<Paint> paintList, ArrayList<String> showAlertTextList) {
        this.maxValue = maxValue;
        this.averageValue = averageValue;
        this.paintList = paintList;
        this.showAlertTextList = showAlertTextList;
        showAlertTextValuesList.clear();
        for (int i = 0; i < (showAlertTextList.size() > yRawData.size() ? showAlertTextList.size() : yRawData.size()); i++) {
            showAlertTextValuesList.add("0");
        }
//        this.mPoints = new Point[yRawData.size()];
        ArrayList<Point[]> arrayList = new ArrayList<>();
        for (int i = 0; i < yRawData.size(); i++) {
            arrayList.add(new Point[yRawData.get(i).size()]);
        }
        this.mPointsLineList = arrayList;
        this.xRawDatas = xBottomRawData;
        this.isShowBottomRawDatas = isShowBottomRawDatas;
        this.isShowTopTextIndexList = isShowTopTextIndexList;
//        this.yRawData = yRawData;
        this.yRawDataLineList = yRawData;
        this.spacingHeight = maxValue / averageValue;

        isShowCoverRound = false;
        isShowVerticalLine = false;

        // 第一次 初始值都为0   onSizeChanged 方法只会走一次,  走过之后就会计算有值
        pointSpace = (canvasWidth - blwidh * 2) / (xRawDatas.size() - 1);
//        Log.e("setData打印:", "pointSpace:" + pointSpace + "  canvasWidth:" + canvasWidth + "  blwidh:" + blwidh + " bwidth:" + bwidth);
        // 重绘一下
        postInvalidate();
    }

    public void clearView(boolean isClearView) {
        this.clearView = isClearView;
        // 重绘一下
        postInvalidate();
    }

    public void clearView(boolean isClearView, String clearAfterShowText) {
        this.clearView = isClearView;
        this.clearAfterShowText = clearAfterShowText;
        // 重绘一下
        postInvalidate();
    }

    public void setTotalvalue(int maxValue) {
        this.maxValue = maxValue;
    }

    public void setPjvalue(int averageValue) {
        this.averageValue = averageValue;
    }

    public void setMargint(int marginTop) {
        this.marginTop = marginTop;
    }

    public void setMarginb(int marginBottom) {
        this.marginBottom = marginBottom;
    }

    public void setMstyle(Linestyle mStyle) {
        this.mStyle = mStyle;
    }

    public void setBheight(int bheight) {
        this.bheight = bheight;
    }

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public int dip2px(float dpValue) {
        return (int) (dpValue * dm.density + 0.5f);
    }
}


package com.zz.kotlintest.view;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.zz.kotlintest.R;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author xifangzheng
 * Created by zz on 2017/10/25 10:35.
 *   class explain:
 *     update:       upAuthor:      explain:
 */

public class LineViewRelativeLayout extends RelativeLayout {

    String LogTag = this.getClass().getSimpleName();
    private LineGraphicView lineGraphicView;
    private TextView moveLine;
    private TextView tvMoveLineTopText;
    private float currentTounchX;
    private LinearLayout llMoveLineCoverRound;
    private ArrayList<String> showAlertTextList;
    private ArrayList<Boolean> isShowTopTextIndexList;
    private ArrayList<String> xBottomRawData;
    private ArrayList<ArrayList<Double>> yRawDataLineList;
    private int leftAddWidth;

    public LineViewRelativeLayout(Context context) {
        this(context, null);
    }

    public LineViewRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        lineGraphicView = new LineGraphicView(context);
        addView(lineGraphicView);

        moveLine = new TextView(context);
        setShowVerticalLine(false);
        addView(moveLine);

        tvMoveLineTopText = new TextView(context);
        setShowVerticalLineTopText(false);
        addView(tvMoveLineTopText);

        llMoveLineCoverRound = new LinearLayout(context);
        addView(llMoveLineCoverRound);

    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        Log.e(LogTag, "onLayout");
    }

    List<TextView> coverRoundTextViewList;

    private void layoutAfterDealMoveLineCoverRound() {
        llMoveLineCoverRound.removeAllViews();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            llMoveLineCoverRound.setBackground(getResources().getDrawable(R.drawable.shape1));
        }
        llMoveLineCoverRound.setOrientation(LinearLayout.VERTICAL);
        coverRoundTextViewList = new ArrayList<>();
        for (int i = 0; i < showAlertTextList.size(); i++) {
            TextView textView = new TextView(getContext());
            textView.setTextSize(12);
            textView.setTextColor(getResources().getColor(R.color.color_999999));
//            textView.setText(showAlertTextList.get(i));
            coverRoundTextViewList.add(textView);
            llMoveLineCoverRound.addView(textView);
        }
        RelativeLayout.LayoutParams layoutParams = (LayoutParams) llMoveLineCoverRound.getLayoutParams();
        layoutParams.addRule(RelativeLayout.LEFT_OF, moveLine.getId());
        layoutParams.width = dip2px(coverRoundWidth);
        layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        layoutParams.topMargin = dip2px(1);
        llMoveLineCoverRound.setPadding(dip2px(coverRoundPaddingLeft), dip2px(coverRoundPaddingTop), dip2px(coverRoundPaddingRight), dip2px(coverRoundPaddingBottom));
        llMoveLineCoverRound.setLayoutParams(layoutParams);
    }

    int coverRoundPaddingLeft = 7;
    int coverRoundPaddingRight = 2;
    int coverRoundPaddingTop = 2;
    int coverRoundPaddingBottom = 2;
    int coverRoundWidth = 58;

    private void layoutAfterDealMoveLineTopText() {
        tvMoveLineTopText.setTextColor(getResources().getColor(R.color.color_999999));
        tvMoveLineTopText.setGravity(Gravity.CENTER);
        tvMoveLineTopText.setTextSize(11);
        tvMoveLineTopText.setText("");
        RelativeLayout.LayoutParams layoutParams = (LayoutParams) tvMoveLineTopText.getLayoutParams();
        layoutParams.addRule(RelativeLayout.ABOVE, moveLine.getId());
        tvMoveLineTopText.setLayoutParams(layoutParams);

    }

    private void layoutAfterDealMoveLine() {
        moveLine.setBackgroundColor(getResources().getColor(R.color.color_DefaultMoveLine));
        moveLine.setWidth(1);
        RelativeLayout.LayoutParams layoutParams = (LayoutParams) moveLine.getLayoutParams();
        layoutParams.topMargin = lineGraphicView.marginTop;
        moveLine.setLayoutParams(layoutParams);
        moveLine.setHeight(lineGraphicView.bheight);

    }

    boolean isShowVerticalLine = false;
    boolean isShowVerticalLineTopText = false;
    boolean isShowMoveLineCoverRound = false;

    private void setShowMoveLineCoverRound(boolean isShowMoveLineCoverRound) {
        this.isShowMoveLineCoverRound = isShowMoveLineCoverRound;
        llMoveLineCoverRound.setVisibility(isShowMoveLineCoverRound ? VISIBLE : INVISIBLE);
    }

    private void setShowVerticalLine(boolean isShowVerticalLine) {
        this.isShowVerticalLine = isShowVerticalLine;
        moveLine.setVisibility(isShowVerticalLine ? VISIBLE : INVISIBLE);
    }

    private void setShowVerticalLineTopText(boolean isShowVerticalLineTopText) {
        this.isShowVerticalLineTopText = isShowVerticalLineTopText;
        tvMoveLineTopText.setVisibility(isShowVerticalLineTopText ? VISIBLE : INVISIBLE);
    }

    private void showView(boolean isShowVerticalLine, boolean isShowVerticalLineTopText, boolean isShowMoveLineCoverRound) {
        setShowVerticalLine(isShowVerticalLine);
        setShowVerticalLineTopText(isShowVerticalLineTopText);
        setShowMoveLineCoverRound(isShowMoveLineCoverRound);
    }

    private void showTouchAfterAll() {
        showView(true, true, true);
    }

    private void hindTouchAfterAll() {
        showView(false, false, false);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (yRawDataLineList == null) {
            return super.onTouchEvent(event);
        }
        currentTounchX = Math.round(event.getX());
        if (currentTounchX <= lineGraphicView.minTouchXPoint) {
            currentTounchX = lineGraphicView.minTouchXPoint;
        } else if (currentTounchX >= lineGraphicView.maxTouchXPoint) {
            currentTounchX = lineGraphicView.maxTouchXPoint;
        }

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                showView(true, true, true);
                break;
            case MotionEvent.ACTION_MOVE:

                break;
            case MotionEvent.ACTION_UP:
//                showView(false, false);
                break;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        dealCurrentTouchX();

//        return super.onTouchEvent(event);
        return true;
    }

    private int currentIndex = -1;
    private int preIndex = -1;

    int valueLength = 2; // 顶部 我的、同行  覆盖区   数字长度判断底值
    int everyAddWidth = 7; // 顶部 我的、同行  覆盖区   数字长度每增加一位 增加的宽度
    int pointAddWidth = 3; // 顶部 我的、同行  覆盖区   包含小数点时 增加的宽度

    private int moveLineSpaceLeftOrRight = 10;

    public void setMoveLineSpaceLeftOrRight(int moveLineSpaceLeftOrRight) {
        this.moveLineSpaceLeftOrRight = moveLineSpaceLeftOrRight;
    }

    private void dealCurrentTouchX() {
        Log.e(LogTag, "当前触摸位置 1 : " + currentTounchX);
        a:
        for (int i = 0; i < lineGraphicView.mPointsLineList.size(); i++) {
            Log.e(LogTag, "onLayout  x space: " + lineGraphicView.pointSpace);
            for (int j = 0; j < lineGraphicView.mPointsLineList.get(i).length; j++) {
                Point point = lineGraphicView.mPointsLineList.get(i)[j];
                if (point != null) {
                    Log.e(LogTag, "point[" + i + "][" + j + "]: x = " + point.x + " y = " + point.y);
                    Log.e(LogTag, "当前触摸位置 2 : " + currentTounchX + "  1  " + (Float.valueOf(point.x) + lineGraphicView.pointSpace / 2));
                    Log.e(LogTag, "当前触摸位置 2 : " + currentTounchX + "  2  " + (Float.valueOf(point.x) - lineGraphicView.pointSpace / 2));
                    if (currentTounchX <= Float.valueOf(point.x) + lineGraphicView.pointSpace / 2
                            && currentTounchX >= Float.valueOf(point.x) - lineGraphicView.pointSpace / 2) {
                        currentTounchX = point.x;
                        Log.e(LogTag, "当前触摸位置 3 : " + currentTounchX);
                        currentIndex = j;
                        if (preIndex != currentIndex) {
                            preIndex = currentIndex;
                            tvMoveLineTopText.setText(isShowTopTextIndexList.get(currentIndex) ? xBottomRawData.get(currentIndex) : "");
                            moveLine.setX(currentTounchX);
                            tvMoveLineTopText.setX(currentTounchX - Float.valueOf(tvMoveLineTopText.getMeasuredWidth() / 2));
int maxLength = 0; // int maxLengthIndex = 0; float maxLengthText = 0; for ( int k = 0; k < yRawDataLineList.size(); k++) { // coverRoundTextViewList.get(k).setText(showAlertTextList.get(k) + ": " + yRawDataLineList.get(k).get(currentIndex)); float textNum = 0; if ( currentIndex < yRawDataLineList.get(k).size()) { textNum = Float. valueOf(String. valueOf( yRawDataLineList.get(k).get( currentIndex))); } if (textNum < 0) { textNum = 0; } String textValue = (textNum == Math. round(textNum) ? String. valueOf(Math. round(textNum)) : String. valueOf(textNum)); coverRoundTextViewList.get(k).setText( showAlertTextList.get(k) + ": " + textValue); if (textValue.length() >= maxLength) { // maxLengthIndex = k; maxLengthText = textNum; maxLength = textValue.length(); } } if (maxLength >= valueLength) { float textNum = maxLengthText; String textValue = (textNum == Math. round(textNum) ? String. valueOf(Math. round(textNum)) : String. valueOf(textNum)); leftAddWidth = (textValue.contains( ".") ? dip2px( pointAddWidth) : 0) + (textValue.replace( ".", "").length() - valueLength) * dip2px( everyAddWidth); } RelativeLayout.LayoutParams layoutParams = (LayoutParams) llMoveLineCoverRound.getLayoutParams(); layoutParams. width = dip2px( coverRoundWidth) + leftAddWidth; layoutParams. height = ViewGroup.LayoutParams. WRAP_CONTENT; llMoveLineCoverRound.setLayoutParams(layoutParams); if ( lineGraphicView. canvasWidth - currentTounchX <= llMoveLineCoverRound.getMeasuredWidth() + dip2px( moveLineSpaceLeftOrRight)) { llMoveLineCoverRound.setX( currentTounchX - ( llMoveLineCoverRound.getMeasuredWidth() + dip2px( moveLineSpaceLeftOrRight))); } else { llMoveLineCoverRound.setX( currentTounchX + dip2px( moveLineSpaceLeftOrRight)); } } break a; } } } } } public void setData(ArrayList<ArrayList<Double>> yRawDataLineList, ArrayList<String> xBottomRawData, ArrayList<Boolean> isShowBottomRawDatas, ArrayList<Boolean> isShowTopTextIndexList, float maxValue, float averageValue, ArrayList<Paint> paintList, ArrayList<String> showAlertTextList) { currentIndex = - 1; preIndex = - 1; hindTouchAfterAll(); this. yRawDataLineList = yRawDataLineList; this. xBottomRawData = xBottomRawData; this. isShowTopTextIndexList = isShowTopTextIndexList; this. showAlertTextList = showAlertTextList; lineGraphicView.setData(yRawDataLineList, xBottomRawData, isShowBottomRawDatas, isShowTopTextIndexList, maxValue, averageValue, paintList, showAlertTextList); layoutAfterDealMoveLine(); layoutAfterDealMoveLineTopText(); layoutAfterDealMoveLineCoverRound(); } public void setDrawCirclePoints( boolean drawCirclePoints) { lineGraphicView.setDrawCirclePoints(drawCirclePoints); } public void setStyle(LineGraphicView.Linestyle mStyle) { lineGraphicView.setStyle(mStyle); } public int dip2px( float dpValue) { return lineGraphicView.dip2px(dpValue); }}

shape1:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">

    <corners android:radius="3dp" />
    <solid android:color="@color/colorWhite" />
    <stroke
        android:width="0.5dp"
        android:color="@color/color_cccccc" />

</shape>

colors:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="colorTransparent">#00000000</color>

    <color name="color_DefaultDrawLine">#ff0000</color>
    <color name="color_DefaultMoveLine">#cccccc</color>
    <color name="color_XLine">#e0e0e0</color>
    <color name="color_99XLine">#99e0e0e0</color>
    <!--<color name="color_YLine">#cccccc</color>-->
    <color name="color_YLine">@color/colorTransparent</color>
    <color name="color_DefaultCoverRoundText">#999999</color>
    <color name="color_cccccc">#cccccc</color>
    <color name="color_999999">#999999</color>
    <color name="color_4c88fc">#4c88fc</color>
    <color name="color_2bd63f">#2bd63f</color>
    <color name="colorWhite">#ffffff</color>
    <color name="colorGreen">#00ff00</color>
    <color name="colorBlue">#0000ff</color>
    <color name="colorRed">#ff0000</color>

    <color name="color_ff3e60">#ff3e60</color>
    <color name="color_ffa200">#ffa200</color>
    <color name="color_31cc64">#31cc64</color>
    <color name="color_3377ff">#3377ff</color>

    <color name="color_LeftText">@color/colorTransparent</color>
    <color name="color_BottomText">#424242</color>

</resources>


activity:  数据自己看着改


package com.zz.kotlintest;

import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.zz.kotlintest.view.LineGraphicView;
import com.zz.kotlintest.view.LineViewRelativeLayout;

import java.util.ArrayList;

/**
 * @Author xifangzheng
 * Created by zz on 2017/9/13 16:30.
 *   class explain:
 *     update:       upAuthor:      explain:
 */

public class LineActivity extends AppCompatActivity {

    private Button btnDataChanges;

    boolean isDataA = true;
    //    private LineGraphicView lineGraphicView;
    private LineViewRelativeLayout lineGraphicView;
    private ArrayList<String> showAlertText;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_line);
        btnDataChanges = (Button) findViewById(R.id.btnDataChanges);
//        lineGraphicView = (LineGraphicView) findViewById(R.id.lineGraphicView);
        lineGraphicView = (LineViewRelativeLayout) findViewById(R.id.lineGraphicView);
        showAlertText = new ArrayList<>();
        showAlertText.add("蓝线");
        showAlertText.add("绿线");
//        showAlertText.add("红线");
        btnDataChanges.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isDataA = !isDataA;
                if (isDataA) {
                    lineGraphicView.setStyle(LineGraphicView.Linestyle.Line);
                    dataA(lineGraphicView);
                } else {
                    lineGraphicView.setStyle(LineGraphicView.Linestyle.Curve);
                    dataB(lineGraphicView);
                }

            }
        });

        dataA(lineGraphicView);

    }

    private void dataA(LineViewRelativeLayout lineGraphicView) {
        ArrayList<ArrayList<Double>> lineListA = new ArrayList<>();
        ArrayList<Double> yList = new ArrayList();
        for (int i = 0; i < 30; i++) {
            yList.add(12.103 + Math.random() * 10);
        }
//        yList.add(5.0);
//        yList.add(9.0);
//        yList1.add(5.0);

        lineListA.add(yList);

        ArrayList<Double> yList1 = new ArrayList();
        for (int i = 0; i < 30; i++) {
            yList1.add(2.103 + Math.random() * 10);
        }

        lineListA.add(yList1);

        ArrayList<String> xRawDatas = new ArrayList<>();
        ArrayList<Boolean> isShowBottomRawDatas = new ArrayList<>();
        ArrayList<Boolean> isShowTopTextIndexList = new ArrayList<>();
        for (int i = 0; i < 30; i++) {
            xRawDatas.add(String.valueOf(i + 1));
        }
        for (int i = 0; i < xRawDatas.size(); i++) {
            isShowBottomRawDatas.add(true);
            isShowTopTextIndexList.add(true);
        }
//        xRawDatas.add("05-26");
//        lineGraphicView.setData(yList, xRawDatas, 8, 2);

        ArrayList<Paint> paintList = new ArrayList<>();
        Paint paint1 = new Paint();
        paint1.setColor(getResources().getColor(R.color.color_4c88fc));
        paint1.setStrokeWidth(lineGraphicView.dip2px(1));
        paint1.setStyle(Paint.Style.STROKE);
//        paint1.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0));
        paintList.add(paint1);

        Paint paint2 = new Paint();
        paint2.setColor(getResources().getColor(R.color.color_2bd63f));
        paint2.setStrokeWidth(lineGraphicView.dip2px(1));
        paint2.setStyle(Paint.Style.STROKE);
        paint2.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
        paintList.add(paint2);

        lineGraphicView.setDrawCirclePoints(false);

        lineGraphicView.setData(lineListA, xRawDatas, isShowBottomRawDatas, isShowTopTextIndexList, 20, 5, paintList, showAlertText);
    }

    private void dataB(LineViewRelativeLayout lineGraphicView) {
        ArrayList<ArrayList<Double>> lineListB = new ArrayList<>();
        ArrayList<Double> yList = new ArrayList<Double>();
        for (int i = 0; i < 5; i++) {
            yList.add(Double.valueOf(Math.round(Math.random() * 1000)));
        }
        lineListB.add(yList);

        ArrayList<Double> yList1 = new ArrayList<Double>();
        yList1.add(Double.valueOf(-1));
        for (int i = 0; i < 2; i++) {
            yList1.add(Double.valueOf(Math.round(Math.random() * 1000)));
        }
        lineListB.add(yList1);

//        ArrayList<Double> yList2 = new ArrayList<Double>();
//        for (int i = 0; i < 20; i++) {
//            yList2.add(Double.valueOf(Math.round(Math.random() * 1000)));
//        }
//        lineListB.add(yList2);

        ArrayList<String> xRawDatas = new ArrayList<String>();
        ArrayList<Boolean> isShowBottomRawDatas = new ArrayList<>();
        ArrayList<Boolean> isShowTopTextIndexList = new ArrayList<>();
        for (int i = 0; i < 7; i++) {
            isShowTopTextIndexList.add(true);
            xRawDatas.add("" + i);
            isShowBottomRawDatas.add(true);
        }

        ArrayList<Paint> paintList = new ArrayList<>();
        Paint paint1 = new Paint();
        paint1.setColor(getResources().getColor(R.color.color_4c88fc));
        paint1.setStrokeWidth(lineGraphicView.dip2px(1));
        paint1.setStyle(Paint.Style.STROKE);
        paint1.setAntiAlias(true);
//        paint1.setPathEffect(new DashPathEffect(new float[]{20, 20}, 0));
        paintList.add(paint1);

        Paint paint2 = new Paint();
        paint2.setColor(getResources().getColor(R.color.color_2bd63f));
        paint2.setStrokeWidth(lineGraphicView.dip2px(1));
        paint2.setStyle(Paint.Style.STROKE);
        paint2.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
        paint2.setAntiAlias(true);
        paintList.add(paint2);

//        Paint paint3 = new Paint();
//        paint3.setColor(getResources().getColor(R.color.color_DefaultDrawLine));
//        paint3.setStrokeWidth(lineGraphicView.dip2px(1));
//        paint3.setStyle(Paint.Style.STROKE);
//        paint3.setPathEffect(new DashPathEffect(new float[]{10, 10}, 0));
//        paint3.setAntiAlias(true);
//        paintList.add(paint3);
        lineGraphicView.setDrawCirclePoints(false);
        lineGraphicView.setData(lineListB, xRawDatas, isShowBottomRawDatas, isShowTopTextIndexList, 1000, 200, paintList, showAlertText);
    }
}





        moveLine.setX(currentTounchX);
        tvMoveLineTopText.setX(currentTounchX - Float.valueOf(tvMoveLineTopText.getMeasuredWidth() / 2));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值