自定义折线、曲线图,根据触摸滑动动态获取值


自定义折线、曲线图,性能一般,还没来得及优化,需要用的可以拿去试一下:

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.os.Build;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
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 {
    /**
     * 公共部分
     */
    private static final int CIRCLE_SIZE = 6;   // 圆点的直径
    private boolean isDrawCirclePoints = true;  //是否画每个圆点
    private ArrayList<ArrayList<Double>> yRawDataLineList; // TODO 自己新增 线的集合
    private ArrayList<Paint> paintList;
    private float pointSpace;   // 两个点之间的 x 轴间距
    private ArrayList<String> showAlertTextList;
    private ArrayList<Boolean> isShowBottomRawDatas;
    private 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;

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

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

    /**
     * 曲线上总点数
     */
    private Point[] mPoints;
    private ArrayList<Point[]> mPointsLineList;    // TODO 新增用来存放所有线的点的集合
    /**
     * 纵坐标值
     */
    private ArrayList<Double> yRawData;
    /**
     * 横坐标值
     */
    private 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 onSizeChanged(int w, int h, int oldw, int oldh) {
        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 = (canvasWidth - blwidh * 2) / (xRawDatas.size() - 1);
//        Log.e("onSizeChanged打印:", "pointSpace:" + pointSpace + "  canvasWidth:" + canvasWidth + "  blwidh:" + blwidh + " bwidth:" + bwidth);
    }

    @Override
    protected void onDraw(Canvas canvas) {

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

        if (isShowVerticalLine) {
            mPaint.setStrokeWidth(2);
            mPaint.setTextSize(dip2px(16));
            mPaint.setColor(res.getColor(R.color.color_DefaultMoveLine));
//            canvas.drawLine(currentTounchX, marginTop, currentTounchX, canvasHeight, mPaint);
            if (isCanShowMoveLineTopText) {
                drawText(moveLineTopText, currentTounchX, marginTop - dip2px(moveLineTopTextSpace), canvas, R.color.color_DefaultCoverRoundText, true, moveLineTopTextTextSize);
            }
            canvas.drawLine(currentTounchX, marginTop, currentTounchX, bheight + marginTop, mPaint);
            if (isShowCoverRound) {
                if (isShowLineRight) {
                    int rightAddWidth = 0;
                    int maxLengthIndex = 0;
                    int maxLength = 0;
                    for (int i = 0; i < showAlertTextValuesList.size(); i++) {
                        float textNum = Float.valueOf(showAlertTextValuesList.get(i));
                        String textValue = (textNum == Math.round(textNum) ? String.valueOf(Math.round(textNum)) : String.valueOf(textNum));
                        if (textValue.length() >= maxLength) {
                            maxLengthIndex = i;
                            maxLength = textValue.length();
                        }
                    }
                    if (maxLength >= valueLength) {
                        float textNum = Float.valueOf(showAlertTextValuesList.get(maxLengthIndex));
                        String textValue = (textNum == Math.round(textNum) ? String.valueOf(Math.round(textNum)) : String.valueOf(textNum));
                        rightAddWidth = (textValue.contains(".") ? dip2px(pointAddWidth) : 0) + (textValue.replace(".", "").length() - valueLength) * dip2px(everyAddWidth);
                    }
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        mPaint.setColor(res.getColor(R.color.colorWhite));
                        mPaint.setStyle(Paint.Style.FILL);
                        canvas.drawRoundRect(currentTounchX + dip2px(coverRoundMarginLeft),
                                dip2px(coverRoundMarginTop),
                                currentTounchX + dip2px(coverRoundWidth) + dip2px(coverRoundMarginLeft) + rightAddWidth,
                                dip2px(coverRoundMarginTop + coverRoundTextMarginTop * (2) + 2 + coverRoundTextVerticalSpacing * (showAlertTextList.size() - 1) + coverRoundTextSize * showAlertTextList.size()),
                                coverRoundRadius, coverRoundRadius, mPaint);
                        mPaint.setColor(res.getColor(R.color.color_cccccc));
                        mPaint.setStyle(Paint.Style.STROKE);
                        canvas.drawRoundRect(currentTounchX + dip2px(coverRoundMarginLeft + 1),
                                dip2px(coverRoundMarginTop + 1),
                                currentTounchX + dip2px(coverRoundWidth) + dip2px(coverRoundMarginLeft) + rightAddWidth,
                                dip2px(coverRoundMarginTop + coverRoundTextMarginTop * (2) + 2 + coverRoundTextVerticalSpacing * (showAlertTextList.size() - 1) + coverRoundTextSize * showAlertTextList.size()),
                                coverRoundRadius, coverRoundRadius, mPaint);
                    }
                    if (showAlertTextList != null && showAlertTextList.size() > 0) {
                        mPaint.setColor(res.getColor(R.color.color_DefaultCoverRoundText));
                        mPaint.setTextSize(dip2px(coverRoundTextSize));
                        mPaint.setStyle(Paint.Style.FILL);
                        mPaint.setTextAlign(Paint.Align.LEFT);
                        for (int i = 0; i < showAlertTextList.size(); i++) {
                            float textNum = Float.valueOf(showAlertTextValuesList.get(i));
                            String textValue = (textNum == Math.round(textNum) ? String.valueOf(Math.round(textNum)) : String.valueOf
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值