自定义View之kotlin绘制折线图实例教程

什么是Kotlin

Kotlin,它是JetBrains开发的基于JVM的面向对象的语言。2017年的时候被Google推荐Android的官方语言,同时Android studio 3.0正式支持这门语言,在这个编译器上创建一个Kotlin项目,非常方便,甚至可以Java转为Kotlin。

引言

早上看到有个童鞋在群里面发牢骚,说这个自定义view怎么画,不太会,ok,正好我也没事,那我就花两个小时帮你搞定他吧,先看下他要的效果;

再来看下我实现的效果

实现过程

主要分为x轴和y轴,由效果图可以看出,x轴主要分为7份,y轴主要分为4份,这样划分就比较简单的知道每条线的位置,每个位置的位置了,绘制起来就很简单;

先绘制y轴的四条线和文字

文字有三个,放到一个list里面,然后我们均分高度,然后遍历文字集合,根绝不同的高度绘制文字和横线
看下代码:

 /**
 * 绘制边框线和边框文本
 */
 private fun drawBorderLineAndText(canvas: Canvas) {
 when {
 valueTextY.size > 0 -> {
 val averageHeight = mNeedDrawHeight / (valueTextY.size + 1)
 (1..valueTextY.size + 1).forEach { i ->
  val nowadayHeight = averageHeight * (valueTextY.size + 1 - i)
  canvas.drawLine(mBrokenLineLeft, nowadayHeight + mBrokenLineTop, mNeedDrawWidth, nowadayHeight + mBrokenLineTop, mBorderLinePaint)
  if (i < valueTextY.size + 1) {
  val fm = mTextPaint.fontMetrics
  val mTxtHeight = Math.ceil((fm.leading - fm.ascent).toDouble()).toInt()
  canvas.drawText(valueTextY[valueTextY.size - i].toString() + "万", mBrokenLineLeft, nowadayHeight + mBrokenLineTop - averageHeight / 2 + mTxtHeight / 2, mTextPaint)
  }
 }

 }
 }
 }

然后绘制x轴的文字

由于文字有6个,我们分为七份,从第一份之后开始绘制:

代码如下:

private fun drawMonthText(canvas: Canvas) {
 when {
 valueOld.size > 0 -> {
 var month = defaultStartMonth
 for (i in 1..valueOld.size) {
  val averageWidth = (mNeedDrawWidth / (valueOld.size + 1)).toInt()
  val fm = mTextPaint.fontMetrics
  val mTxtHeight = Math.ceil((fm.leading - fm.ascent).toDouble()).toInt()
  canvas.drawText(month.toString() + "月", (averageWidth * i).toFloat(), mNeedDrawHeight - mTxtHeight / 2, mTextPaint)
  month++
 }
 }
 }
 }

最后绘制折线和折现上面的小球

这里我们需要把数据放进两个集合传入,然后根据数据算出每个点的坐标,最后根据path把每个点连接起来就ok了;

代码如下:

 /**
 * 设置点的值
 */
 fun setPointValues(valueNew: ArrayList<Int>, valueOld: ArrayList<Int>) {
 this.valueNew = valueNew
 this.valueOld = valueOld
 }
 /**
 * 根据值计算在该值的 x,y坐标
 */
 fun getPoints(list: ArrayList<Int>): ArrayList<Point> {
 val avaregwidth = mNeedDrawWidth / (list.size + 1)
 val points = ArrayList<Point>(list.size)
 list.indices.forEach { i ->
  val valueY = list[i].toFloat()
  val averaHeight = (mNeedDrawHeight * 3 / 4 / maxValue).toDouble()
  val drawHeight = mNeedDrawHeight * 3 / 4 - (valueY * averaHeight).toFloat() + mBrokenLineTop
  val pointY = drawHeight.toInt()
  val pointX = ((avaregwidth * (i + 1)).toInt() + mBrokenLineLeft).toInt()
  val point = Point(pointX, pointY)
  points.add(point)
 }
 return points
 }
/**
 * 根据值绘制折线
 */
 private fun drawBrokenLine(canvas: Canvas) {
 when {
  valueOld.size > 0 && valueNew.size > 0 -> {
  val mPathOld = Path()
  val mPathNew = Path()
  val mPathOldshadow = Path()
  val mPathNewshadow = Path()
  val pointsOld = getPoints(valueOld)
  val pointsNew = getPoints(valueNew)
  for (i in 0 until mAnimatorValue) {
   val pointOld = pointsOld[i]
   val pointNew = pointsNew[i]
   if (i == 0) {
   mPathOld.moveTo(pointOld.x.toFloat(), pointOld.y.toFloat())
   mPathNew.moveTo(pointNew.x.toFloat(), pointNew.y.toFloat())

   mPathOldshadow.moveTo(pointOld.x.toFloat(), pointOld.y.toFloat())
   mPathNewshadow.moveTo(pointNew.x.toFloat(), pointNew.y.toFloat())
   } else {
   mPathOld.lineTo(pointOld.x.toFloat(), pointOld.y.toFloat())
   mPathNew.lineTo(pointNew.x.toFloat(), pointNew.y.toFloat())

   mPathOldshadow.lineTo(pointOld.x.toFloat(), pointOld.y.toFloat())
   mPathNewshadow.lineTo(pointNew.x.toFloat(), pointNew.y.toFloat())
   }
  }
  mBrokenLinePaint.color = Color.parseColor("#ff5400")
  canvas.drawPath(mPathOld, mBrokenLinePaint)
  mBrokenLinePaint.color = Color.parseColor("#ffff00")
  canvas.drawPath(mPathNew, mBrokenLinePaint)
  }
 }
 }

 /**
 * 绘制线上的圆
 */
 private fun drawLineCircle(canvas: Canvas) {
 when {
  valueOld.size > 0 && valueNew.size > 0 -> {
  val pointsOld = getPoints(valueOld)
  val pointsNew = getPoints(valueNew)
  for (i in 0 until mAnimatorValue) {
   val pointOld = pointsOld[i]
   val pointNew = pointsNew[i]
   mCirclePaint.color = Color.parseColor("#ff5400")
   canvas.drawCircle(pointOld.x.toFloat(), pointOld.y.toFloat(), radius, mCirclePaint)
   mCirclePaint.color = Color.parseColor("#ffff00")
   canvas.drawCircle(pointNew.x.toFloat(), pointNew.y.toFloat(), radius, mCirclePaint)
  }
  }
 }
 }

最后就是添加动画了,可有可无,看需求吧

代码如下:

 private fun initAnimator( size:Int) {
 valueAnimator = ValueAnimator.ofInt(0, size).setDuration(defaultDuration.toLong())
 mUpdateListener = ValueAnimator.AnimatorUpdateListener { animation ->
  mAnimatorValue = animation.animatedValue as Int
  invalidate()
 }
 valueAnimator.addUpdateListener(mUpdateListener)
 valueAnimator.start()
 }

 fun setPointValues(valueNew: ArrayList<Int>, valueOld: ArrayList<Int>) {
 this.valueNew = valueNew
 this.valueOld = valueOld
 initAnimator(valueNew.size)
 }

这样大体效果就已经实现了,最后加阴影,就更简单了,就直接给画笔设置阴影就行了

喜欢请到github点个赞啦

地址:github (本地下载)

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Android 使用Kotlin自定义View的方法教程

    前言 随着google宣布kotlin作为官方开发语言,在Android中使用kotlin的趋势也越来越明显,最近被kotlin的文章轰炸了,所以决定上手试一下,试过之后,感觉靠它灵简直有魔性.特别是一句话写出一个复杂的循环的时候,简直被惊呆.而且使用AS,Java代码可以直接转成Kotlin. 效果图如下: 首先是这次自定义View的效果图,是一张饼图.如果是用java写的话也就几十行,觉得换成Kotlin的话可能会更少. 示例代码 主要的功能是可以任设定数据的个数,我这里是4个数据,可以任意

  • 自定义View系列之kotlin绘制手势设置温度控件的方法

    引言 最近公司接了一个车联网的项目,主要是新能源汽车的一些控制功能,其中涉及到一个是温度的调节功能,产品的意思是做一个手势滑动调节温度,大概意思我是明白的.就是要手势调节呗,没办法,谁让我是搬砖的呢,人为刀俎,我为鱼肉,只有搞了: 最后搞出来的效果大概如下,不过还没确定, 思路 在这里我先说下自己的实现思路,这个控件的难点主要是手势控制,其他的都很简单,没有什么好说的,控制的一些具体的数值我是写死的,没有做自定义拓展,主要是闲麻烦,如果有需要可以自己的实现: 具体的实现步奏 首先绘制圆盘,刻度,

  • Kotlin自定义View系列教程之标尺控件(选择身高、体重等)的实现

    前言 本篇文章讲的是Kotlin 自定义view之实现标尺控件Ruler,以选择身高.体重等.开发中,当我们需要获取用户的身高和体重等信息时,如果直接让他们输入,显然体验不够好.像类似于唯品会.好轻等APP都是使用了类似于刻度尺的控件让用户滑动选择身高体重,觉得很棒.网上已有人使用Java语言实现这样的功能,但不影响我对其的学习.和往常一样,主要还是想总结一下自定义view之实现标尺控件的开发过程以及一些需要注意的地方. 按照惯例,我们先来看看效果图 一.先总结下自定义View的步骤: 1.自定

  • 自定义View之kotlin绘制折线图实例教程

    什么是Kotlin Kotlin,它是JetBrains开发的基于JVM的面向对象的语言.2017年的时候被Google推荐Android的官方语言,同时Android studio 3.0正式支持这门语言,在这个编译器上创建一个Kotlin项目,非常方便,甚至可以Java转为Kotlin. 引言 早上看到有个童鞋在群里面发牢骚,说这个自定义view怎么画,不太会,ok,正好我也没事,那我就花两个小时帮你搞定他吧,先看下他要的效果; 再来看下我实现的效果 实现过程 主要分为x轴和y轴,由效果图可

  • R语言绘制折线图实例分析

    折线图是通过在它们之间绘制线段来连接一系列点的图. 这些点在它们的坐标(通常是x坐标)值之一中排序. 折线图通常用于识别数据中的趋势. R语言中的plot()函数用于创建折线图. 语法 在R语言中创建折线图的基本语法是 - plot(v,type,col,xlab,ylab) 以下是所使用的参数的描述 - v是包含数值的向量. 类型采用值"p"仅绘制点,"l"仅绘制线和"o"绘制点和线. xlab是x轴的标签. ylab是y轴的标签. main是

  • QT中QChart绘制折线图

    目录 一.简单绘图 二.绘制折线图 实例 一.简单绘图 Qt Charts基于Qt的Graphics View架构,其核心组件是QChartView 和 QChart QChartView是显示图标的视图,基类为QGraphicsView QChart的基类是QGraphicsltem 类的继承关系: 创建项目:.pro文件中添加:QT += charts代码如下:其他文件未修改,修改代码只在mainwindow.cpp文件中进行.mainwindow.cpp #include "mainwin

  • jquery.flot.js简单绘制折线图用法示例

    本文实例讲述了jquery.flot.js简单绘制折线图用法.分享给大家供大家参考,具体如下: 1.完整实例代码: <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>折线图</title> <!--[if lte IE 8]> <script language="javascript" type="text/javas

  • Angular2使用SVG自定义图表(条形图、折线图)组件示例

    本文实例讲述了Angular2使用SVG自定义图表(条形图.折线图)组件.分享给大家供大家参考,具体如下: 要求:用户将数据作为参数传进来,通过类型决定渲染何种类型的图标. demo: html: <ngo-chart [inputParams]="options"></ngo-chart> ts: options = { type: 'line', //图表类型 xAxis: { //X轴的数据 data: ['Mon', 'Tue', 'Wed', 'Thu

  • Android实现绘制折线图APP代码

    目录 一.总体设计 二.具体模块实现 三.效果展示 四.功能展望 总结 一.总体设计 1.寻找规律,公式化的生成坐标系. 2.将生成坐标系的关键参数设置为可自定义,从而可变的可以生成自己想要的坐标系. 3.将需要绘制的点绘制在坐标系中并生成折现图. 二.具体模块实现 1.坐标系的生成: public void chart(){ imageView=(ImageView)findViewById(R.id.image); newb = Bitmap.createBitmap(w, h, Bitma

  • Python基于Matplotlib库简单绘制折线图的方法示例

    本文实例讲述了Python基于Matplotlib库简单绘制折线图的方法.分享给大家供大家参考,具体如下: Matplotlib画折线图,有一些离散点,想看看这些点的变动趋势: import matplotlib.pyplot as plt x1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] y1=[30,31,31,32,33,35,35,40,47,62,99,186,480] x2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 1

  • Android自定义View实现等级滑动条的实例

     Android自定义View实现等级滑动条的实例 实现效果图: 思路: 首先绘制直线,然后等分直线绘制点: 绘制点的时候把X值存到集合中. 然后绘制背景图片,以及图片上的数字. 点击事件down的时候,换小图片为大图片.move的时候跟随手指移动. up的时候根据此时的X计算最近的集合中的点,然后自动吸附回去. 1,自定义属性 <?xml version="1.0" encoding="utf-8"?> <resources> <de

  • JS+html5 canvas实现的简单绘制折线图效果示例

    本文实例讲述了JS+html5 canvas实现的简单绘制折线图效果.分享给大家供大家参考,具体如下: 1.实例代码: <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <title>画图</title> <style> #divContainer{ margin-top: 20px; text-align: center; } #cv{ width: 300px;

  • Android自定义View实现箭头沿圆转动实例代码

    具体代码如下所示: //MyCircleView类 public class MyCircleView extends View{ //当前画笔画圆的颜色 private int CurrenCircleBoundColor; private Paint paint; ////从xml中获取的颜色 private int circleBundColor; private float circleBoundWidth; private float pivotX; private float piv

随机推荐