自定义曲线图

和折线图实现的效果差不多,先贴代码

package com.wisdudu.community.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


import java.util.List;

/**
 * Created by pc on 2016/3/8.
 */
public class DiagramView extends View {
    private Context myContext;
    public int paddingLeft;
    public int paddingRight;
    public int paddingBottom;
    public int paddintTop;

    int width;  //控件宽度
    int height; //控件高度
    List<Double> listDate1;  //数据源
    double maxDate;  //集合最大值,占满整个高度
    int jgwidth; //2点间隔宽度
    public int index;  //当前选中的index;
    List<String> listString1;
    List<String> listString2;
    
    int[] x;
    int[] y;

    static boolean isFist=true;//第一次进来,用于判断点显示不显示要用的
    boolean isInit=false;      //是否已经传过来初始化所有参数,没有的话,view不显示,ondraw里面判断





    public DiagramView(Context context) {
        super(context);
        this.myContext=context;
    }

    public DiagramView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.myContext=context;
    }

    public DiagramView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.myContext=context;
    }


    public void setInit(List<Double> listDate1,List<String> listString1, List<String> listString2){
        this.listDate1=listDate1;
        this.listString1=listString1;
        this.listString2=listString2;
        isInit=true;
        initDatas();
        invalidate();

    }


    public static enum Type{
        week,month
    }
    /**
     * 初始化数据
     */
    public void initDatas(){
        maxDate=getMaxint();  //算出最大的数
        paddingLeft=0;
        paddingRight=0;
        paddingBottom=30;
        paddintTop=120;
        x=new int[listDate1.size()];
        y=new int[listDate1.size()];


        jgwidth=(getWidth()-paddingLeft-paddingRight)/(listDate1.size()-1);

        //算出来个坐标点
        for(int i=0;i<listDate1.size();i++){
            double kuan=getMyWeight(i);
            double gao=getMyHeight(listDate1.get(i));
            x[i]=(int)kuan;
            y[i]=(int)gao;
        }



        for(int i=0;i<listDate1.size();i++){
            if(maxDate==listDate1.get(i)){
                index=i;
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(!isInit){
            return;
        }
        if (isFist){
            initDatas();
            isFist=false;
        }
        canvas.drawColor(Color.parseColor("#49acd5"));

        //绘制任意多边形
        Paint paint = new Paint();
        //设置画笔颜色
        paint.setColor(Color.parseColor("#10a679"));
        //设置圆弧的宽度
        paint.setStrokeWidth(10);
        //设置圆弧为空心
        paint.setStyle(Paint.Style.STROKE);
        //消除锯齿
        paint.setAntiAlias(true);
        Path path = new Path();
        path.moveTo(((int)x[0]), (int)y[0]);

        for(int i=0;i<listDate1.size()-1;i++){


            int wt = (x[i] + x[i+1]) / 2;
            Point p3 = new Point();
            Point p4 = new Point();
            p3.y = y[i];
            p3.x = wt;
            p4.y = y[i+1];
            p4.x = wt;

            path.cubicTo(p3.x, p3.y, p4.x, p4.y, x[i+1],y[i+1]);


        }
        path.lineTo(getWidth()-paddingLeft,getHeight());
        path.lineTo(paddingLeft,getHeight());
        path.lineTo(((int)x[0]), (int)y[0]);
        paint.setStyle(Paint.Style.FILL);

        Shader mShader=new LinearGradient(0,paddintTop,0,getHeight(),
                new int[]{ Color.parseColor("#85c8e4"),Color.parseColor("#49acd5")},
                null,Shader.TileMode.MIRROR);
//        参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点,最后参数为平铺方式
        paint.setShader(mShader);
        canvas.drawPath(path, paint);


        /**
         * 画圆外部蓝色
         */
        paint = new Paint();
        //设置画笔颜色
        paint.setColor(Color.parseColor("#3FFFFFFF"));
        //设置圆弧的宽度
        paint.setStrokeWidth(1);
        //设置圆弧为空心
        paint.setStyle(Paint.Style.FILL);
        //消除锯齿
        paint.setAntiAlias(true);
        for(int item=0;item<listDate1.size();item++){
           if(index==item){
               if(item==0){
                   //定义一个矩形
                   RectF rf2 = new RectF(x[item]-15+15, y[item]-15, x[item]+15+15, y[item]+15);
                   //画圆
                   canvas.drawOval(rf2, paint);
               }else if(item==listDate1.size()-1){
                   //定义一个矩形
                   RectF rf2 = new RectF(x[item]-15-15, y[item]-15, x[item]+15-15, y[item]+15);
                   //画圆
                   canvas.drawOval(rf2, paint);
               }else{
                   //定义一个矩形
                   RectF rf2 = new RectF(x[item]-15, y[item]-15, x[item]+15, y[item]+15);
                   //画圆
                   canvas.drawOval(rf2, paint);
               }
           }
        }


        /**
         * 画圆内部白色
         */
        paint = new Paint();
        //设置画笔颜色
        paint.setColor(Color.parseColor("#72FFFFFF"));
        //设置圆弧的宽度
        paint.setStrokeWidth(1);
        //设置圆弧为空心
        paint.setStyle(Paint.Style.FILL);
        //消除锯齿
        paint.setAntiAlias(true);
        for(int item=0;item<listDate1.size();item++){
            if(index==item){
                if(item==0){
                    //定义一个矩形
                    RectF rf2 = new RectF(x[item]-10+15, y[item]-10, x[item]+10+15, y[item]+10);
                    //画圆
                    canvas.drawOval(rf2, paint);
                }else if(item==listDate1.size()-1){
                    //定义一个矩形
                    RectF rf2 = new RectF(x[item]-10-15, y[item]-10, x[item]+10-15, y[item]+10);
                    //画圆
                    canvas.drawOval(rf2, paint);
                }else{
                    //定义一个矩形
                    RectF rf2 = new RectF(x[item]-10, y[item]-10, x[item]+10, y[item]+10);
                    //画圆
                    canvas.drawOval(rf2, paint);
                }
            }


        }



        //画7个直线
        /**
         */
        paint = new Paint();
        paint.setColor(Color.parseColor("#FFFFFF"));
        paint.setStrokeWidth(1);
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true);
        for(int item=0;item<listDate1.size();item++){
           if(index==item){
               //定义一个矩形
               if(item==0){
                   canvas.drawLine(x[item]+15,y[item]+15,x[item]+15,getHeight(),paint);
               }else if(item==listDate1.size()-1){
                   //定义一个矩形
                   canvas.drawLine(x[item]-15,y[item]+15,x[item]-15,getHeight(),paint);
               }else{
                   canvas.drawLine(x[item],y[item]+15,x[item],getHeight(),paint);
               }
           }
        }




        //绘制文字
        paint = new Paint();
        paint.setFakeBoldText(false); //true为粗体,false为非粗体
        //mp.setTextSkewX(-0.5f); //float类型参数,负数表示右斜,整数左斜
        //mp.setUnderlineText(true); //true为下划线,false为非下划线
        //mp.setStrikeThruText(true); //true为删除线,false为非删除线
        paint.setTextSize(24); //设置字体大小,int型,如12
        paint.setShader(null);
        paint.setStrokeWidth(10);
        paint.setColor(Color.WHITE);

        for (int i=0;i<x.length;i++){
            if(index==i){
                    if(i==0){
                        canvas.drawText(listString1.get(i),x[i]-30+30,y[i]-30,paint);
                    }else if(i==listDate1.size()-1){
                        Log.e("-->","进来了");
                        canvas.drawText(listString1.get(i),x[i]-30-50,y[i]-30,paint);
                    }else{
                        canvas.drawText(listString1.get(i),x[i]-30,y[i]-30,paint);
                    }

            }
        }



        for (int i=0;i<x.length;i++){
            if(index==i){
                    if(i==0){
                        canvas.drawText(listString2.get(i),x[i]-30+30,y[i]-30-25,paint);
                    }else if(i==listDate1.size()-1){
                        Log.e("-->","进来了");
                        canvas.drawText(listString2.get(i),x[i]-30-50,y[i]-30-25,paint);
                    }else{
                        canvas.drawText(listString2.get(i),x[i]-30,y[i]-30-25,paint);
                    }


            }
        }

    }


    public double getMaxint(){
        double max=0;
        for (int i=0;i<listDate1.size();i++){
            if(listDate1.get(i)>max){
                max=listDate1.get(i);
            }
        }
        return max;
    }

    //穿入数据源返回数据源应有的高度
    public double getMyHeight(double d){
        int height=getHeight()-paddintTop;
        return (height-(height*(d/maxDate)))+paddintTop;
    }



    public double getMyWeight(int posotion){
        return posotion*jgwidth+paddingLeft;
    }



    boolean pd1=false;
    boolean pd2=false;
    float mx1,mx2,my1,my2;
    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:  //按下 = 0
                mx1=event.getX();
                my1=event.getY();
                if(pd1){
                    pd1=false;
                }
                pd1=true;
                Log.e("-->","按下");
                break;
            case MotionEvent.ACTION_MOVE:  //移动 = 2
                pd2=true;
                Log.e("-->","移动");
                break;
            case MotionEvent.ACTION_UP:    // 抬起 = 1
                mx2=event.getX();
                my2=event.getY();
                float number=mx1-mx2>0?mx1-mx2:mx2-mx1;
                if(pd1&pd2&number>10){
                    if(number>10){
                        Log.e("-->","滑动");
                        if((mx1-mx2)>0){
                            Log.e("-->","往左边滑动");
                            index=index>0?index-1:index;
                        }else{
                            Log.e("-->","往右边滑动");
                            index=index<listDate1.size()-1?index+1:index;
                        }
                        invalidate();
                    }
                }else{
                    int item=isok(event.getX(),event.getY());
                     index=item==-1?index:item;
                    invalidate();
                    Log.e("-->","抬起");
                }
                break;
        }

        //gestureDetector.onTouchEvent(event);
        return true;
    }
    //判断点和矩形是否相交
    public boolean isXiangjiao(float dx,float dy,int juBeginX,int juBeginY,int juEndX,int juEndY) {
        if(dx>=juBeginX&dy>=juBeginY&dx<=juEndX&dy<=juEndY){
            return true;
        }else{
            return false;
        }
    }

    //判断点击的坐标是否在个圆圈里面,是则返回圈的下标,不是返回-1
    public int isok(float djx,float djy){
        for(int i=0;i<x.length;i++){
            if(isXiangjiao(djx,djy,x[i]-60, y[i]-90, x[i]+60, y[i]+60)){
                return i;
            }
        }
        return -1;
    }

}

测试activity

package com.example.pc.test.Activity;

import android.app.Activity;
import android.os.Bundle;


import com.example.pc.test.R;

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


public class MainActivity extends Activity
{
    DiagramView myView;
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        myView= (DiagramView) findViewById(R.id.myView);

        List<Double> listDate1=new ArrayList<>();
        listDate1.add(25.0);
        listDate1.add(20.0);
        listDate1.add(25.0);
        listDate1.add(20.0);
        listDate1.add(25.0);
        listDate1.add(20.0);
        listDate1.add(25.0);


        List<String> listDate2=new ArrayList<>();
        listDate2.add("586分");
        listDate2.add("886分");
        listDate2.add("386分");
        listDate2.add("586分");
        listDate2.add("36分");
        listDate2.add("856分");
        listDate2.add("836分");



        List<String> listDate3=new ArrayList<>();
        listDate3.add("9.20AM");
        listDate3.add("9.20AM");
        listDate3.add("19.20AM");
        listDate3.add("93.20AM");
        listDate3.add("9w.20AM");
        listDate3.add("9x.20AM");
        listDate3.add("9.20AM");


        myView.setInit(listDate1,listDate2,listDate3);
    }
}


act xml引用自定义view,设置数据源即可.

效果图:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值