Canvas和Paint画折线图

前言

前在Devstore上传了一个折线图的小功能,有挺多人下载的,所以今天把它拿来给大家分享一下。

正文

网上有很多关于折线图之类的功能,有简单的、复杂的。但是有一些折线图不利于扩展,很难拿到自己的项目中去运用。我给大家介绍的简单、使用,并且利于扩展,先看看我最初做成的样子吧:
这里写图片描述
后来公司又有一个项目用到了,就把它拿来修改一下,感觉效果还不错:
这里写图片描述
还可以吧!

这里主要用Canvas(画布)、Paint(画笔)、Color(颜色)、Bitmap(图像)这几种graphics中常用的类来实现,先来对它们进行讲解(这里我直接把从网上找了一下关于它们的讲解,感觉还不错就拿来了)。

1.Color(颜色)类:
  Android系统中颜色的常用表示方法有以下3种:
  (1)int color = Color.BLUE;
  (2)int color = Color.argb(150,200,0,100);
  (3)在xml文件中定义颜色;
  在实际应用当中,我们常用的颜色有以下一些,其颜色常量及其表示的颜色如下所示:
  Color.BLACK 黑色 Color.GREEN 绿色
  Color.BLUE 蓝色 Color.LTGRAY 浅灰色
  Color.CYAN 青绿色 Color.MAGENTA 红紫色
  Color.DKGRAY 灰黑色 Color.RED 红色
  Color.YELLOW 黄色 Color.TRANSPARENT 透明
  Color.GRAY 灰色 Color.WHITE 白色
2.Paint(画笔)类:
  要绘制图形,首先得调整画笔,按照自己的开发需要设置画笔的相关属性。Pain类的常用属性设置方法如下:
  setAntiAlias(); //设置画笔的锯齿效果
  setColor(); //设置画笔的颜色
  setARGB(); //设置画笔的A、R、G、B值
  setAlpha(); //设置画笔的Alpha值
  setTextSize(); //设置字体的尺寸
  setStyle(); //设置画笔的风格(空心或实心)
  setStrokeWidth(); //设置空心边框的宽度
  getColor(); //获取画笔的颜色
3.Canvas(画布)类:
  画笔属性设置好之后,还需要将图像绘制到画布上。Canvas类可以用来实现各种图形的绘制工作,如绘制直线、矩形、圆等等。Canvas绘制常用图形的方法如下:
  绘制直线:canvas.drawLine(float startX, float startY, float stopX, float stopY, Paint paint);
  绘制矩形:canvas.drawRect(float left, float top, float right, float bottom, Paint paint);
  绘制圆形:canvas.drawCircle(float cx, float cy, float radius, Paint paint);
  绘制字符:canvas.drawText(String text, float x, float y, Paint paint);
  绘制图形:canvas.drawBirmap(Bitmap bitmap, float left, float top, Paint paint);
4.折线图的实现:
给大家讲的折线图的实现,分为两部分:
1、画横线,添加纵坐标;
2、根据坐标画出点,并划线连接每一个点;
5.代码实现:
这个功能的代码写的挺简单的,主要是三个类;一个主类(MainActivity),画纵坐标(ShiViews),画点和折线(ShiView);
首先看看一下布局activity_main.xml:

 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@color/black" >
    <!-- 纵线布局 -->
    <LinearLayout 
      android:id="@+id/lays"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:background="@null">
    </LinearLayout>
    <!-- 折线布局 -->
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:background="@null">
        <HorizontalScrollView 
           android:id="@+id/scrollview"
           android:layout_height="wrap_content"
           android:layout_width="fill_parent"
           android:scrollbars="none">
        <LinearLayout 
            android:id="@+id/lay"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
             android:orientation="horizontal">
        </LinearLayout>
    </HorizontalScrollView>
    </FrameLayout>
</FrameLayout>

MianActivity的主要代码:

    /** 画点和折线的类 */
    ShiView ssvv = new ShiView(context,temp,temps,time);
    LayoutParams lpp = new LayoutParams(1500, 600);
    ssvv.setLayoutParams(lpp);
    lay.addView(ssvv);
    /** 画纵坐标和横线 */
    ShiViews ssvvs = new ShiViews(context);
    LayoutParams lpps = new LayoutParams(1500, 600);
    ssvvs.setLayoutParams(lpps);
    lays.addView(ssvvs);

ShiView类:
ShiView继承于View类。然后,复写View类的onDraw()函数。在onDraw()函数中使用Paint和Canvas对象绘制我们需要的图形。
这里就直接给大家上代码吧,因为相对来说没有复杂的逻辑并且代码中有相关注释:

int[] temp = new int[7];
    int[] temps = new int[7];
    String[] dayTime = new String[7];
    private Context context;
    private Canvas canvass;
    private Paint paint;
    private Paint paints;
    public ShiView(Context context, int[] temp, int[] temps, String[] dayTime) {
        super(context);
        this.temp = temp;
        this.temps = temps;
        this.dayTime = dayTime;
        this.context = context;
    }
    public ShiView(Context context) {
        super(context);
    }
    public ShiView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        canvass = canvas;
        paint = new Paint(); 
        paints = new Paint(); 
        /* 去锯齿 */ 
        paint.setAntiAlias(true); 
        paints.setAntiAlias(true); 

        //纵坐标
        paint.reset();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL); 
        paint.setStrokeWidth(2); 
        paint.setTextSize(20); 
        //横坐标
        for(int i=0;i<7;i++){
            canvas.drawText(dayTime[i], i*200+100, 590, paint);
        }
        //画折线
        paint.reset();
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE); 
        paint.setStrokeWidth(2); 
        paints.reset();
        paints.setColor(Color.RED);
        paints.setTextSize(25);
        paints.setStyle(Paint.Style.STROKE); 
        paints.setStrokeWidth(2); 
        Path path = new Path(); 
        Path paths = new Path(); 
        path.moveTo(115,  560-temp[0]*16);
        paths.moveTo(115,  560-temps[0]*16);
        for(int i=1;i<7;i++){
            path.lineTo(i*200+115,  560-temp[i]*16);
            paths.lineTo(i*200+115,  560-temps[i]*16);
        }
        canvas.drawPath(path, paint); 
        canvas.drawPath(paths, paint); 
        paint.reset();
        paint.setColor(Color.WHITE); 
        // 设置样式-填充 
        paint.setStyle(Style.FILL); 
        // 绘图 // 从资源文件中生成位图 
        for(int i=0;i<7;i++){
            int tempy = (int)temp[i];
            int tempsy = (int)temps[i];
            if((tempy - tempsy) < 4 && (tempy - tempsy) > 0){
                canvas.drawText(temp[i]+"", i*200+105, 540-temp[i]*(float)16, paints);
                canvas.drawText(temps[i]+"", i*200+105, 595-temps[i]*(float)16, paints);
            }else if((tempy - tempsy) > -4 && (tempy - tempsy) < 4 && (tempy - tempsy) < 0){
                canvas.drawText(temp[i]+"", i*200+105, 595-temp[i]*(float)16, paints);
                canvas.drawText(temps[i]+"", i*200+105, 540-temps[i]*(float)16, paints);
            }else{
                canvas.drawText(temp[i]+"", i*200+105, 540-temp[i]*(float)16, paints);
                canvas.drawText(temps[i]+"", i*200+105, 540-temps[i]*(float)16, paints);
            }
            canvas.drawCircle(i*200+115, 560-temp[i]*(float)16, 12, paint);
            canvas.drawCircle(i*200+115, 560-temps[i]*(float)16, 12, paint);
        }
    }
    /** 点击屏幕获得坐标判断点击位置 */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
          float x = event.getX();   
          float y = event.getY();   
          for(int i=0;i<7;i++){
              float tempx = i*200+115;
              float tempys = 560-temps[i]*(float)16;
              float tempy = 560-temp[i]*(float)16;
              if(x >= (tempx-15)  && x <= (tempx+15) && y <= tempys+15 && y >= tempys-15){
                  canvass.drawCircle(i*200+115, 560-temps[i]*(float)16, 12, paint);
                  Toast.makeText(context,temps[i]+"", Toast.LENGTH_SHORT).show();
                  break;
              }
              if(x >= (tempx-15)  && x <= (tempx+15) && y <= tempy+15 && y >= tempy-15){
                  Toast.makeText(context,temp[i]+"", Toast.LENGTH_SHORT).show();
                  break;
              }
          }
          return super.onTouchEvent(event);
    }

ShiViews类的相关内容在ShiView这个类里面都有,也不进行讲解了;
代码下载地址,有不懂得或者意见的可以相互沟通,晚安。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值