自定义控件之折线图

自定义的漂亮的折线图,给大家分享一下



直接上代码

acitivity布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/background"
    tools:context="mylinear.zhang.com.mychartview.MyLineaActivity">

    <mylinear.zhang.com.mychartview.utils.ChartView
        android:id="@+id/mychart"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:charttitle="折线图测试"
        app:introduce="折线图测试"
        app:lineColor="@android:color/holo_red_light" />
</LinearLayout>

activity代码

package mylinear.zhang.com.mychartview;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

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

import mylinear.zhang.com.mychartview.utils.ChartView;

public class MyLineaActivity extends AppCompatActivity {
    private ChartView chartView;
    private static final String[] XLabels = {"30", "40", "50", "60", "70", "80", "90", "100", "110", "120"};
    private final String[] YLables = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
    private final int[] colors = {Color.parseColor("#C01F2E"), Color.parseColor("#F26921"), Color.parseColor("#F26921"), Color.parseColor("#FCB040"), Color.parseColor("#0B9245"), Color.parseColor("#0B9245"), Color.parseColor("#FCB040"),
            Color.parseColor("#F26921"), Color.parseColor("#F26921"), Color.parseColor("#C01F2E")};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my_linea);
        chartView = (ChartView) findViewById(R.id.mychart);

        initview();
    }
//初始化数据,生成20个30到120之间的随机数传入自定义控件
    public void initview() {
        List PHRData = new ArrayList<>();
        Random random = new Random();
        int PHRmax = 120, PHRmin = 30;
        for (int i = 0; i < 20; i++) {
            float s = random.nextInt(PHRmax) % (PHRmax - PHRmin + 1) + PHRmin;
            PHRData.add(s);
        }
        chartView.SetInfo(YLables, XLabels, colors, PHRData, 30, 10);
    }
}

接下来看自定控件的自定义属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyChartView">
        <attr name="charttitle" format="string"/>
        <attr name="introduce" format="string"/>
        <attr name="lineColor" format="color"/>
    </declare-styleable>
</resources>


再看自定义折线图的代码

package mylinear.zhang.com.mychartview.utils;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;

import java.util.List;

import mylinear.zhang.com.mychartview.R;

public class ChartView extends View {

    private  int[] colors ;

    private float XPoint; // 原点的X坐标
    private float YPoint; // 原点的Y坐标
    private float XScale; // X的刻度长度
    private float YScale; // Y的刻度长度

    //    private int YNumberScale;//Y轴标注刻度
    private float Xmin;//X轴最大值
    private float numberSpace;

    private float XTextScale;
    private float XLength; // X轴的长度
    private float YLength; // Y轴的长度
    private String[] XLabel; // X的刻度
    private String[] YLabel; // Y的刻度
    private List<Float> Data; // 数据
    private String Title = ""; // 显示的标题
    private String introduce = "";
    private int linearColor;

    private Paint xPaint;
    private Paint yPaint;
    private Paint dataPaint;
    private Paint yTxtPaint;
    private Paint xTxtPaint;
    private Paint titlePaint;

    private int screenWidth;
    private int screenHeight;

    private float XTextLength;

    private Context mContext;

    public ChartView(Context context) {
        super(context);
        this.mContext = context;
    }

    public ChartView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyChartView);
        Title = typedArray.getString(R.styleable.MyChartView_charttitle);
        introduce = typedArray.getString(R.styleable.MyChartView_introduce);
        linearColor = typedArray.getInt(R.styleable.MyChartView_lineColor, Color.parseColor("#ffffff"));
        typedArray.recycle();
    }

    public ChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
    }

    /**
     * @param XLabels     x轴标签
     * @param YLabels     y轴标签
     * @param colors      x轴颜色可以为每两个刻度之间设置不同的颜色
     * @param AllData     数据List<Float>
     * @param Xmin        x轴起始值
     * @param numberSpace x轴刻度之间相差数值
     */
    public void SetInfo(String[] XLabels, String[] YLabels, int[] colors, List<Float> AllData, int Xmin, int numberSpace) {
        this.XLabel = XLabels;
        this.YLabel = YLabels;
        this.Data = AllData;
        this.Xmin = Xmin;
        this.numberSpace = numberSpace;
        this.colors=colors;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);// 重写onDraw方法

        XPoint = DensityUtils.dp2px(mContext, 40);
        YPoint = screenHeight - DensityUtils.dp2px(mContext, 25);

        XLength = (screenWidth - DensityUtils.dp2px(mContext, 40));
        YLength = (screenHeight - DensityUtils.dp2px(mContext, 50));

        XScale = XLength / XLabel.length;
        YScale = YLength / YLabel.length;


        XTextLength = XLength / XLabel.length * XLabel.length;
        XTextScale = XTextLength / XLabel.length;


        xPaint = new Paint();
        xPaint.setStyle(Paint.Style.STROKE);
        xPaint.setAntiAlias(true);// 去锯齿
        xPaint.setColor(getResources().getColor(R.color.chartviewline));// 颜色
        xPaint.setStrokeWidth((float) DensityUtils.dp2px(mContext, 1));

        xTxtPaint = new Paint();
        xTxtPaint.setStyle(Paint.Style.STROKE);
        xTxtPaint.setAntiAlias(true);// 去锯齿
        xTxtPaint.setColor(Color.WHITE);// 颜色
        xTxtPaint.setTextSize(DensityUtils.sp2px(mContext, 7)); // 设置轴文字大小

        titlePaint = new Paint();
        titlePaint.setStyle(Paint.Style.STROKE);
        titlePaint.setAntiAlias(true);// 去锯齿
        titlePaint.setColor(Color.WHITE);// 颜色
        titlePaint.setTextSize(DensityUtils.sp2px(mContext, 20)); // 设置轴文字大小

        yPaint = new Paint();
        yPaint.setStyle(Paint.Style.STROKE);
        yPaint.setAntiAlias(true);// 去锯齿
        yPaint.setColor(getResources().getColor(R.color.white));// 颜色
        yPaint.setStrokeWidth((float) DensityUtils.dp2px(mContext, 5));

        yTxtPaint = new Paint();
        yTxtPaint.setStyle(Paint.Style.STROKE);
        yTxtPaint.setAntiAlias(true);// 去锯齿
        yTxtPaint.setColor(Color.WHITE);// 颜色
        yTxtPaint.setTextSize(DensityUtils.sp2px(mContext, 8)); // 设置轴文字大小

        dataPaint = new Paint();
        dataPaint.setStyle(Paint.Style.FILL);
        dataPaint.setAntiAlias(true);// 去锯齿
        dataPaint.setColor(linearColor);// 颜色
        dataPaint.setTextSize(22); // 设置轴文字大小
        dataPaint.setStrokeWidth(DensityUtils.dp2px(mContext, 1));

        // 刻度
        for (int i = 0; i < YLabel.length; i++) {
            //Y轴刻度
            canvas.drawText(YLabel[i], XPoint - DensityUtils.dp2px(mContext, 25), YPoint - i * YScale
                    + DensityUtils.dp2px(mContext, 2), yTxtPaint); // 文字
            //X轴线
            canvas.drawLine(XPoint, YPoint - i * YScale, XPoint + XLength - XLength / XLabel.length, YPoint - i * YScale, xPaint);
        }
        //Y轴线
        for (int i = 0; i < YLabel.length - 1; i++) {
            if (colors!=null){
                if (colors[i] != 0) {
                    yPaint.setColor(colors[i]);
                }
            }else {
                yPaint.setColor(Color.WHITE);
            }
            canvas.drawLine(XPoint - DensityUtils.dp2px(mContext, 3), YPoint - i * YScale, XPoint - DensityUtils.dp2px(mContext, 3), YPoint - YScale * (i + 1), yPaint);
        }

        // 设置X轴
        canvas.drawLine(XPoint, YPoint, XPoint + XLength - XLength / XLabel.length, YPoint, xPaint); // 轴线
        canvas.drawText(Title, XPoint - DensityUtils.dp2px(mContext, 15), YPoint - YLength + YScale - DensityUtils.dp2px(mContext, 15), titlePaint);
        Rect rect = new Rect();
        titlePaint.getTextBounds(Title, 0, Title.length(), rect);
        int w = rect.width();
        canvas.drawText(introduce, XPoint + w, YPoint - YLength + YScale - DensityUtils.dp2px(mContext, 15), xTxtPaint);


        for (int i = 0; i < XLabel.length; i++) {
            canvas.drawText(XLabel[i], XPoint + i * XTextScale, YPoint + DensityUtils.dp2px(mContext, 10),
                    xTxtPaint); // 文字

        }
        drawChart(canvas);
    }

    private void drawChart(Canvas canvas) {
        for (int i = 0; i < XLabel.length - 1; i++) {
            if (Data.get(i) != null) {
                canvas.drawLine(XPoint + i * XScale,
                        YPoint - (Data.get(i) - Xmin) / numberSpace * YScale,
                        XPoint + (i + 1) * XScale,
                        YPoint - (Data.get(i + 1) - Xmin) / numberSpace * YScale,
                        dataPaint);
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = measureWidth(widthMeasureSpec);
        int height = measureHeight(heightMeasureSpec);
        this.screenWidth = width;
        this.screenHeight = height;
        setMeasuredDimension(width, height);
    }

    //根据xml的设定获取宽度
    private int measureWidth(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //wrap_content
        if (specMode == MeasureSpec.AT_MOST) {

        }
        else if (specMode == MeasureSpec.EXACTLY) {

        }

        return specSize;
    }

    //根据xml的设定获取高度
    private int measureHeight(int measureSpec) {
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);
        //wrap_content
        if (specMode == MeasureSpec.AT_MOST) {

        }
        else if (specMode == MeasureSpec.EXACTLY) {

        }
        return specSize;
    }

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值