自定义折线Demo

测试机一般,效果图可能看不太清,不要紧。后面我会跟上所有源代码,放到自己的demo中就能跑起来

先来个效果图
这里写图片描述

说明:随着手指的移动,会有一条竖线,竖线和折现交点处,会有小圆圈出现,而且,还有出现水平的横线。最后,会通过一个回调接口,把对应的在Y轴上的刻度值返回。

代码中有详细的注释说明。关于一点细节的东西,会在最后说明

获取交点处高度值的回调接口
GetHeightData

public interface GetHeightData {

    /**
     * 返回的是百分比
     */
    void getHeightData(float f1, float f2);

}

LinePicBean

import java.io.Serializable;

public class LinePicBean implements Serializable{


    public LinePicBean(float actualData) {
        this.actualData=actualData;
    }

    //真实数据
    private float actualData;
    private float actualHeight;

    public float getActualData() {
        return actualData;
    }
    public void setActualData(float actualData) {
        this.actualData = actualData;
    }
    public float getActualHeight() {
        return actualHeight;
    }
    public void setActualHeight(float actualHeight) {
        this.actualHeight = actualHeight;
    }

}

自定义折现
Line


import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Shader.TileMode;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

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

public class Line extends View {
    /**
     * 控件的高度
     */
    private int vHeight;
    /**
     * 控件的宽度
     */
    private int vWidth;
    /**
     * 第一条折现的路径画笔
     */
    private Paint pathPaint;
    /**
     * 第一条折现的路径
     */
    private Path path;
    /**
     * 第一条折现的闭合区域路径
     */
    private Path regionPath;
    /**
     * 第一条折现的闭合区域的画笔
     */
    private Paint regionPaint;
    private Paint moveLinePaint;// 跟随手指移动的线的画笔
    private Paint circlePaint;// 绘制小圆环画笔
    private Paint circlePoint;// 绘制小圆点画笔
    /**
     * 用于保存传递过来的,第一条折现的数据的集合
     */
    private List<LinePicBean> originalData;

    /**
     * X轴刻度坐标的集合(不包含Y方向坐标)
     */
    private List<Float> XList = new ArrayList<Float>();
    /**
     * 预留高度,用来显示底部刻度
     */
    private float surplusHeight;
    /**
     * 顶部预留高度,为纵轴文字高度的一半
     */
    private float topSurplusHeight;
    /**
     * 代表竖直最大刻度
     */
    private float total;
    // --------------------------------------------------------
    private Paint pathPaint2;// 路径画笔,就是折线
    private Path path2;// line路径
    private Path regionPath2;// 闭合区域路径
    private Paint regionPaint2;// 区域画笔,画渐变区域
    private Paint moveLinePaint2;// 跟随手指移动的线的画笔
    private Paint circlePaint2;// 绘制小圆环画笔
    private Paint circlePoint2;// 绘制小圆点画笔
    private List<LinePicBean> originalData2;
    private List<Float> XList2 = new ArrayList<Float>();
    // ---------------------------------------------------------

    /**
     * Y轴上的刻度上的文字画笔
     */
    private TextPaint verticalTextPaint;
    /**
     * 水平线画笔
     */
    private Paint horiPaint;
    /**
     * X轴刻度上的文字画笔
     */
    private TextPaint horizontalTextPaint;

    public Line(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    public Line(Context context, AttributeSet attrs) {
        this(context, attrs, -1);
    }

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

    public void setData(List<LinePicBean> list) {
        XList.clear();
        this.originalData = list;
        int length = list.size();
        for (int i = 0; i < length; i++) {
            /*
            vWidth - maxLength,是横坐标(X轴)的实际长度。
            如果有5个刻度,需要被分成4份,所以要除以(length - 1)
            因为X轴实际开始位置距离控件左边的距离是Y周数据的宽度,所以,最后要加上maxLength
             */
            XList.add((vWidth - maxLength) * 1.0f / (length - 1) * i
                    + maxLength);
        }

        LinePicBean linePicBean = null;
        for (int i = 0; i < length; i++) {
            linePicBean = originalData.get(i);

             /*
             * 原始数据是5.0、0、-3.0、6.5、4.0。通过下面这句的计算后,结果是10.0、2.0、0.0、11.5、9.0
             *
             * 这里固定加5,是因为Y周刻度的最低是 -5.0
             *
             * 这里需要额外注意,不要单纯的去加折线数据中的最小值的绝对值
             *
             * 以当前demo为例,Y轴刻度最小是 -5,第一条折线的最小数据是 -3
             *
             * 如果单纯的加折线最小值,就成了 -3+|-3|=0,后面,再除以12.5(7.5+|-5|),结果是0
             * 意味着,这个-3,在Y轴的最低点。而Y轴刻度最低是-5,这显然不对
             *
             * 现在 -3+|-5|=2,2/12.5=0.16,也就是说,-3对应的高度,是12.5(整个Y轴高度)的0.16,这就对了
             *
             */
            linePicBean.setActualData(linePicBean.getActualData() + 5);

            // 这个12.5是纵轴范围总和,到时候根据项目需要动态计算(7.5+5.0)
            /*
            * topSurplusHeight:顶部预留高度,为纵轴文字高度的一半
            * total = vHeight - surplusHeight,控件的总高度减去底部刻度预留高度。表示Y轴的高度
            * total - topSurplusHeight表示有刻度的区域。示例中,表示-5.0%--7.5%之间的高度
            * 最高是7.5,最低是-5.0,所以,总值是7.5+5.0=12.5
            * linePicBean.getActualData() / (12.5f),表示当前坐标点再Y轴的位置比例。如第一个点:10.0/12.5=0.8
            *(total - topSurplusHeight) * linePicBean.getActualData() / (12.5f),将比例换算成高度值(像素)
            *安卓的坐标系,想下是Y轴正方向,所以,需要total减去上面计算的值,这样,就换成了在屏幕的Y轴的坐标
            */
            linePicBean.setActualHeight(total - (total - topSurplusHeight) * linePicBean.getActualData() / (12.5f));
        }

        //确定折现的起点
        path.moveTo(XList.get(0), originalData.get(0).getActualHeight());
        //确定折现下方的渐变区域的起点
        regionPath.moveTo(XList.get(0), originalData.get(0).getActualHeight());

        //确定每个坐标点
        for (int i = 1; i < length; i++) {
            path.lineTo(XList.get(i), originalData.get(i).getActualHeight());
            regionPath.lineTo(XList.get(i), originalData.get(i).getActualHeight());
        }

        //定位到坐标系的右下角
        regionPath.lineTo(XList.get(length - 1), total);

        //定位到坐标系的左下角(X轴和Y轴交点处)
        regionPath.lineTo(maxLength, total);

        //最后需要close,组成一个闭合区域
        regionPath.close();

        //绘制
        invalidate();
    }

    public void setData2(List<LinePicBean> list) {
        //注释详见setData方法

        XList2.clear();
        this.originalData2 = list;
        int length = list.size();
        for (int i = 0; i < length; i++) {
            XList2.add((vWidth - maxLength) * 1.0f / (length - 1) * i
                    + maxLength);
        }

        LinePicBean linePicBean = null;
        for (int i = 0; i < length; i++) {
            linePicBean = originalData2.get(i);
            linePicBean.setActualData(linePicBean.getActualData() + 5);
            linePicBean.setActualHeight(total - (total - topSurplusHeight)
                    * linePicBean.getActualData() / 12.5f);
        }

        path2.moveTo(XList2.get(0), originalData2.get(0).getActualHeight());
        regionPath2.moveTo(XList2.get(0), originalData2.get(0)
                .getActualHeight());
        for (int i = 1; i < length; i++) {
            path2.lineTo(XList2.get(i), originalData2.get(i).getActualHeight());
            regionPath2.lineTo(XList2.get(i), originalData2.get(i)
                    .getActualHeight());
        }
        regionPath2.lineTo(XList2.get(length - 1), total);
        regionPath2.lineTo(maxLength, total);
        regionPath2.close();
        invalidate();
    }

    private GetHeightData listener;

    public void setListener(GetHeightData listener) {
        this.listener = listener;
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        vHeight = h;
        vWidth = w;

        /*
         * LinearGradient(线性渐变)是Shader下的一个子类
         *详细的请看一位大神的博客
         * http://blog.csdn.net/aigestudio/article/details/41799811
         */
        LinearGradient gradient = new LinearGradient(0, vHeight, 0, 0,
                Color.parseColor("#00ffffff"), Color.parseColor("#6629bbea"),
                TileMode.REPEAT);
        regionPaint.setShader(gradient);
        LinearGradient gradient2 = new LinearGradient(0, vHeight, 0, 0,
                Color.parseColor("#00ffffff"), Color.parseColor("#66e44078"),
                TileMode.REPEAT);
        regionPaint2.setShader(gradient2);
    }

    private void init() {

        verticalLength = 20;
        pathPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        pathPaint.setStyle(Style.STROKE);// 不设置Style为STROKE,DashPathEffect不起作用
        regionPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        regionPaint.setStyle(Style.FILL);
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setStyle(Style.STROKE);
        circlePaint.setStrokeWidth(5);
        circlePoint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePoint.setStrokeWidth(10);
        horiPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        horiPaint.setStyle(Style.STROKE);

        moveLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        moveLinePaint.setColor(Color.RED);
        verticalTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        verticalTextPaint.setTextSize(20);
        verticalTextPaint.setColor(Color.parseColor("#0000ff"));

        path = new Path();
        regionPath = new Path();
        pathPaint.setColor(Color.parseColor("#29bbea"));
        circlePaint.setColor(Color.parseColor("#29bbea"));
        circlePoint.setColor(Color.parseColor("#29bbea"));

        pathPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        pathPaint2.setStyle(Style.STROKE);
        regionPaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        regionPaint2.setStyle(Style.FILL);
        circlePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint2.setStyle(Style.STROKE);
        circlePaint2.setStrokeWidth(5);
        circlePoint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePoint2.setStrokeWidth(10);
        moveLinePaint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
        moveLinePaint2.setColor(Color.BLACK);
        horizontalTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        horizontalTextPaint.setTextSize(20);
        horizontalTextPaint.setColor(Color.parseColor("#00ff00"));
        path2 = new Path();
        regionPath2 = new Path();
        pathPaint2.setColor(Color.parseColor("#e44078"));
        circlePaint2.setColor(Color.parseColor("#e44078"));
        circlePoint2.setColor(Color.parseColor("#e44078"));
    }

    private float radius = 10f;

    /**
     * 手指所在位置的竖线和折线交点处的圆环的半径
     */
    private float largeRadius = 15f;

    /**
     * Y轴上,刻度和刻度之间的距离
     */
    private float verticalMeanValue = 0;
    /**
     * 文字基线和文字正中间的那条横线之间的差值
     */
    private float offsetDistance;
    /**
     * X轴上,文字顶部的小竖线的高度
     */
    private float verticalLength;

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        /*
         * total - topSurplusHeight表示有刻度的区域
         * verticalScaleList.size()表示Y轴上刻度的个数
         *
         * verticalMeanValue:Y轴上,刻度和刻度之间的距离。就是有刻度的区域,根据刻度个数得到的平均值
         */
        verticalMeanValue = (total - topSurplusHeight) / (verticalScaleList.size() - 1);

        //根据Y轴的刻度绘制水平的线
        for (int i = 0; i < verticalScaleList.size(); i++) {

            canvas.drawLine(maxLength, total - verticalMeanValue * i, vWidth, total - verticalMeanValue * i, horiPaint);

            //绘制文字。就是在坐标系上写刻度
            canvas.drawText(verticalScaleList.get(i), 0, total - verticalMeanValue * i + offsetDistance, verticalTextPaint);
        }

        //绘制X轴上刻度位置的小竖线和文字

        for (int i = 0; i < horizontalScaleList.size(); i++) {

            canvas.drawLine(XList.get(i), total, XList.get(i), total + verticalLength, horiPaint);

            if (i == 0) {
                horizontalTextPaint.setTextAlign(Align.LEFT);
            } else if (i == horizontalScaleList.size() - 1) {
                horizontalTextPaint.setTextAlign(Align.RIGHT);
            } else {
                horizontalTextPaint.setTextAlign(Align.CENTER);
            }

            //绘制文字。就是在坐标系上写刻度
            canvas.drawText(horizontalScaleList.get(i), XList.get(i), total + verticalLength + (horiTextHeight - horiOffsetDistance), horizontalTextPaint);
        }

        //绘制第一条折现
        canvas.drawPath(path, pathPaint);
        //绘制第一条折现下方的渐变区域
        canvas.drawPath(regionPath, regionPaint);
        //绘制第二条折现
        canvas.drawPath(path2, pathPaint2);
        //绘制第二条折现下方的渐变区域
        canvas.drawPath(regionPath2, regionPaint2);

        if (flag) {
            canvas.drawLine(X, topSurplusHeight, X, total, moveLinePaint);
            canvas.drawLine(maxLength, Y, vWidth, Y, moveLinePaint);
            canvas.drawLine(maxLength, YY2, vWidth, YY2, moveLinePaint);
            canvas.drawCircle(X, YY2, largeRadius, circlePaint2);
            canvas.drawCircle(X, Y, largeRadius, circlePaint);

            if (listener != null) {
                listener.getHeightData(f1, f2);
            }

        } else {
            if (listener != null) {
                listener.getHeightData(-1, -1);
            }
        }
        for (int i = 0; i < originalData.size(); i++)// 绘制小圆点
        {
            canvas.drawCircle(XList.get(i), originalData.get(i)
                    .getActualHeight(), radius, circlePoint);
        }
        for (int i = 0; i < originalData2.size(); i++)// 绘制小圆点
        {
            canvas.drawCircle(XList2.get(i), originalData2.get(i)
                    .getActualHeight(), radius, circlePoint2);
        }

    }

    /**
     * 手指按下未位置的X坐标
     */
    private float X;
    /**
     * 标记是否出现竖直线
     */
    private boolean flag;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        X = event.getX();

        getRegionY(X);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                if (X < maxLength) {
                    flag = false;
                } else {
                    flag = true;
                }

                break;
            case MotionEvent.ACTION_MOVE:
                if (X < maxLength) {
                    flag = false;
                } else {
                    flag = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                //如果想松开手,线还在,就注释掉这句话
                //flag = false;
                break;
            default:
                break;
        }

        invalidate();
        return true;
    }

    private float Y;
    private float YY2;

    private float f1;
    private float f2;

    //获取圆环的Y坐标值
    private void getRegionY(float x) {
        for (int i = 0; i < XList.size() - 1; i++) {
            if (x == XList.get(i) || x == XList.get(i + 1) || (x > XList.get(i) && x < XList.get(i + 1))) {
                //X坐标在X轴的2个连续的刻度之间

                float X1 = XList.get(i);
                float Y1 = total - originalData.get(i).getActualHeight();
                float X2 = XList.get(i + 1);
                float Y2 = total - originalData.get(i + 1).getActualHeight();

                /*
                 * 这里的要算出一个随手指移动的垂直的线和折现的焦点的Y坐标值(X坐标就是手指按下的位置),计算涉及方程
                 *
                 * 现在,在X轴上,相邻的2个刻度之间的区域(包括区域边界),肯定有2个点(X1,Y1)、(X2,Y2)
                 * 直线方程基础表达式:y=ax+b
                 * 斜率 a=(Y2 - Y1) / (X2 - X1)
                 * 所以,这个区间的直线方程就是:y=(Y2 - Y1) / (X2 - X1)x+b
                 * 随便代入一个点的坐标:如:(X1,Y1)
                 * 得到b=(Y1 * X2-Y2 * X1)/ (X2 - X1)
                 * 所以,折线在这个区间的线性方程就是:y=(Y2 - Y1) / (X2 - X1) * x + (Y1 * X2-Y2 * X1) / (X2 - X1)
                 *
                 * 另一条直线,就是手指所在位置的一条垂直的线,方程是:x=手指按下的位置,就是方法上传进来的值
                 *
                 * 代入方程就得到了y的值。
                 * 但是要注意,这个y值,是数学上坐标系的Y坐标的值,安卓是屏幕左上角为原点,向下为Y周正方向
                 * 所以,在这个控件中,这个点的Y方向的高度,实际是:total-y
                 *
                 */
                f1 = ((Y2 - Y1) / (X2 - X1) * x + (Y1 * X2 - Y2 * X1) / (X2 - X1)) / (total - topSurplusHeight);
                Y = total - (Y2 - Y1) / (X2 - X1) * x + (Y2 * X1 - Y1 * X2) / (X2 - X1);
            }
        }

        for (int i = 0; i < XList2.size() - 1; i++) {
            if (x == XList2.get(i) || x == XList2.get(i + 1) || (x > XList2.get(i) && x < XList2.get(i + 1))) {
                float X1 = XList2.get(i);
                float Y1 = total - originalData2.get(i).getActualHeight();
                float X2 = XList2.get(i + 1);
                float Y2 = total - originalData2.get(i + 1).getActualHeight();
                f2 = ((Y2 - Y1) / (X2 - X1) * x + (Y1 * X2 - Y2 * X1) / (X2 - X1)) / (total - topSurplusHeight);
                YY2 = total - (Y2 - Y1) / (X2 - X1) * x + (Y2 * X1 - Y1 * X2) / (X2 - X1);
            }
        }
    }

    /**
     * 存放Y轴刻度上的值
     */
    private List<String> verticalScaleList = new ArrayList<String>();
    /**
     * 记录纵坐标上的最长的数字的长度
     */
    private float maxLength = 0;

    /**
     * 设置Y轴相关
     *
     * @param verticalScaleList Y轴刻度的集合
     */
    public void setVerticalAbout(List<String> verticalScaleList) {
        this.verticalScaleList = verticalScaleList;
        //通过下面的for循环,拿到最长的那个数字值
        String maxString = "";
        for (int i = 0; i < verticalScaleList.size(); i++) {
            if (verticalScaleList.get(i).length() > maxString.length()) {
                maxString = verticalScaleList.get(i);
            }
        }
        maxLength = verticalTextPaint.measureText(maxString);

        /*
         * 下坡度-上坡度,就是文字的整个高度,因为预留高度是一半,所以除以2
         * 从基线开始,向上到文字最高处,是上坡度,因为和安卓屏幕坐标系Y方向相反,所以是一个负数值。其绝对值表示上坡度大小
         * 从基线开始,向下到文字最底部,是下坡度,因为和安卓屏幕坐标系Y方向相同,所以是一个正数值。其值表示下坡度大小
         *
         * 如果不理解文字的上下坡度等熟悉,详见一位大神博客
         * http://blog.csdn.net/aigestudio/article/details/41447349
         */
        topSurplusHeight = (verticalTextPaint.descent() - verticalTextPaint.ascent()) / 2;

        total = vHeight - surplusHeight;

        /*
         * ascent(上坡度)<0,descent(下坡度)>0,|上坡度|>下坡度
         * -verticalTextPaint.descent() - verticalTextPaint.ascent() = -下坡度+|上坡度|
         * 除以2,就是文字基线和文字正中间的那条横线之间的差值
         */
        offsetDistance = (-verticalTextPaint.descent() - verticalTextPaint.ascent()) / 2;
    }

    private List<String> horizontalScaleList = new ArrayList<String>();
    private float horiTextHeight;
    private float horiOffsetDistance;

    /**
     * 设置X轴相关
     *
     * @param horizontalScaleList X轴刻度集合
     */
    public void setHorizontalAbout(List<String> horizontalScaleList) {
        this.horizontalScaleList = horizontalScaleList;
        horiTextHeight = (horizontalTextPaint.descent() - horizontalTextPaint.ascent());
        horiOffsetDistance = (-horizontalTextPaint.descent() - horizontalTextPaint.ascent()) / 2;

        surplusHeight = horiTextHeight * 2;
    }

}

在布局中引用

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">

    <com.line.demo.Line
        android:id="@+id/line"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="10dp"
        android:background="#55ff0000"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="蓝线"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/line_data_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:textSize="20sp"/>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="红线"
            android:textSize="20sp"/>

        <TextView
            android:id="@+id/line_data_2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:textSize="20sp"/>

    </LinearLayout>

</LinearLayout>

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewTreeObserver;
import android.widget.TextView;

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

public class MainActivity extends Activity implements GetHeightData {
    private Line line;
    private List<LinePicBean> lists;
    private List<LinePicBean> lists1;
    /**
     * Y轴的刻度
     */
    private List<String> verticalScale;
    /**
     * 水平X轴的刻度
     */
    private List<String> horizontalScale;

    private TextView line_data_1;
    private TextView line_data_2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        line = findViewById(R.id.line);
        line_data_1 = findViewById(R.id.line_data_1);
        line_data_2 = findViewById(R.id.line_data_2);

        lists = new ArrayList<LinePicBean>();
        lists.clear();
        lists.add(new LinePicBean(5.0f));
        lists.add(new LinePicBean(0f));
        lists.add(new LinePicBean(-3.0f));
        lists.add(new LinePicBean(3f));
        lists.add(new LinePicBean(4.0f));
        lists1 = new ArrayList<LinePicBean>();
        lists1.clear();
        lists1.add(new LinePicBean(2.5f));
        lists1.add(new LinePicBean(0f));
        lists1.add(new LinePicBean(2.5f));
        lists1.add(new LinePicBean(6.0f));
        lists1.add(new LinePicBean(7.5f));

        //Y轴的标识
        verticalScale = new ArrayList<String>();
        verticalScale.add("-5.0%");
        verticalScale.add("-2.5%");
        verticalScale.add("0%");
        verticalScale.add("2.5%");
        verticalScale.add("5.0%");
        verticalScale.add("7.5%");

        //横轴的标识
        horizontalScale = new ArrayList<String>();
        horizontalScale.add("02/05");
        horizontalScale.add("02/06");
        horizontalScale.add("02/07");
        horizontalScale.add("02/08");
        horizontalScale.add("02/09");

        line.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {// 想办法只让执行一次

                    @Override
                    public void onGlobalLayout() {

                        line.getViewTreeObserver().removeGlobalOnLayoutListener(this);

                        //设置X轴相关
                        line.setHorizontalAbout(horizontalScale);
                        //设置Y轴相关
                        line.setVerticalAbout(verticalScale);
                        line.setData(lists);
                        line.setData2(lists1);
                        line.setListener(MainActivity.this);
                    }
                });

    }


    @Override
    public void getHeightData(float f1, float f2) {



        Log.e("f1", f1 + "");
        Log.e("f2", f2 + "");

        if (f1 == -1 || f2 == -1) {
            line_data_1.setText("");
            line_data_2.setText("");
        } else {

//            line_data_1.setText(f1 * 12.5 - 5.0f + "");
//            line_data_2.setText(f2 * 12.5 - 5.0f + "");
            line_data_1.setText(f1 * 12.5f - 5.0f + "");
            line_data_2.setText(f2 * 12.5f - 5.0f + "");

        }

    }
}

说明:
大家应该注意到了,在最后展示返回值的时候,我写了2种,第一种是

    line_data_1.setText(f1 * 12.5 - 5.0f + "");
    line_data_2.setText(f2 * 12.5 - 5.0f + "");

有个特殊点,当竖线移动到Y为0的时候,
这里写图片描述

出现的是这样的很小的一个值。

但是,当我把展示方法换成第二种

 line_data_1.setText(f1 * 12.5f - 5.0f + "");
 line_data_2.setText(f2 * 12.5f - 5.0f + "");

展示就成了
这里写图片描述

所以,为展示数据准确,最好全部用同一种数据类型。

猜你喜欢

转载自blog.csdn.net/u014620028/article/details/78569646
今日推荐