热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android版的股票行情K线图开发

这篇文章主要介绍了Android版的股票行情K线图开发,感兴趣的小伙伴们可以参考一下

现在在手上的是一个证券资讯类型的app,其中有涉及到股票行情界面,行情中有K线图等,看到网上很多人在求这方面的资料,所以我特地写了一个demo在此处给大家分享一下。

下面是做出来的效果图:

背景图是利用canvas先画出一个矩形,然后再画几根虚线,均线图是通过path来绘制的,总之图的绘制是很简单的,我就不在这里作介绍了,大家可以去github下载源码看看。涉及到均线、最高价、最低价、收盘价、开盘价的概念大家可以百度一下。

我再这里要介绍的是计算问题:

大家可以看到分时图、日K、月K的左边的成交价格都是不一样的,而我们的k线都是通过这个价格来绘制的,也就是说价格是时刻变动,那么我们的k线绘制也是变动的。假设我们要计算分时图中价格为25.69的那一分钟应该如何画,画在屏幕中的哪一个位置,那么这个应该怎么画呢,价格是变动的,画的位置也是变动的,但是有一点我们屏幕的大小是不变的。所以我们可以通过背景图的高度来计算某个价格的线图应该从哪个地方开始画。我们可以计算出一个像素点对应多少个价格,分析图如下:

价格和像素形成个一个比例计算是:double   heightScale = (endY - startY)/(highPrice - lowPrice);

所以价格25.69应该是画在mStartY = (float) (startY+ (highPrice - 25.69) * heightScale);

这个明白了之后其他的原理都是一样的,我就不介绍了,下面是部分代码:

@Override 
  protected void drawKChatBackGround() { 
    Rect dirty = new Rect(left, kChartTop, right, KChartbottom); 
    // 画背景图的矩形 
    mCanvas.drawRect(dirty, LineGrayPaint); 
    PathEffect effects = new DashPathEffect(new float[] { 5, 5, 5, 5 }, 1); 
    LineGrayPaint.setPathEffect(effects); 
    Path path = new Path(); 
    int y = kChartTop + 15; 
    // 画上面的虚线 
    path.moveTo(left, y ); 
    path.lineTo(right, y ); 
    String text = getPriceText(highPrice); 
    int textHeight = (int) (textGrayPaint.descent() - textGrayPaint.ascent()); 
    mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2 ,textGrayPaint); 
    double max = highPrice - lowPrice; 
    if (max > 10){ 
      // 分成四等分 
      // 画中间的三根虚线 
      int n = 4; 
      double sper = (highPrice - lowPrice) / 4;// 每一等分代表的价格 
      for(int i=1;i 0; i--) { 
      int x = left + perWidth * i; 
      path.moveTo(x, kChartTop); 
      path.lineTo(x, KChartbottom); 
      perXPoint[i - 1] = x; 
    } 
    mCanvas.drawPath(path, LineGrayPaint); 
  } 

@Override 
  protected void drawMAChart() { 
    // 画均线 
    Path path5 = new Path(); 
    Path path10 = new Path(); 
    Path path20 = new Path(); 
    double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice); 
    int maStart = left; 
    float maStartY; 
    path5.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue5()) * heightScale)); 
    path10.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue10()) * heightScale)); 
    path20.moveTo(maStart, (float) (kChartTop + (highPrice - infos.get(0).getMaValue20()) * heightScale)); 
     
    for(SingleStockInfo info:infos){ 
      maStart += per * perHalf;// 每一天实际所占的数据是4/6,左右边距各1/6  
      maStartY = (float) (kChartTop + (highPrice - info.getMaValue5()) * heightScale); 
      path5.lineTo(maStart, maStartY); 
      maStartY = (float) (kChartTop + (highPrice - info.getMaValue10()) * heightScale); 
      path10.lineTo(maStart, maStartY); 
      maStartY = (float) (kChartTop + (highPrice - info.getMaValue20()) * heightScale); 
      path20.lineTo(maStart, maStartY); 
      maStart += per * perHalf; 
    } 
     
    Paint paint = new Paint(); 
    paint.setColor(Color.BLUE); 
    paint.setAntiAlias(true); 
    paint.setStrokeWidth(2); 
    paint.setStyle(Style.STROKE); 
    mCanvas.drawPath(path5, paint); 
    paint.setColor(Color.MAGENTA); 
    mCanvas.drawPath(path10, paint); 
    paint.setColor(Color.GREEN); 
    mCanvas.drawPath(path20, paint); 
  }
/** 
   * 下面的柱形图 
   */ 
  @Override 
  protected void drawPillarsChart(int flag) { 
    LineGrayPaint.setPathEffect(null); 
    Rect dirty = new Rect(left, pillarsChartTop, right, pillarsChartbottom); 
    // 画背景图的矩形 
    mCanvas.drawRect(dirty, LineGrayPaint); 
     
    int y = pillarsChartTop + (pillarsChartbottom - pillarsChartTop)/2; 
    mCanvas.drawLine(left,y,right, y, LineGrayPaint); 
     
    // 中间的值 
    String totalCount = getPriceText(maxCount/2/10000); 
    float maginLeft = left - textGrayPaint.measureText(totalCount)- 5; 
    mCanvas.drawText(totalCount, maginLeft, y,textGrayPaint); 
    // 上面的值 
    totalCount = getPriceText(maxCount/10000); 
    maginLeft = left - textGrayPaint.measureText(totalCount)- 5; 
    mCanvas.drawText(totalCount, maginLeft, pillarsChartTop,textGrayPaint); 
    // 下面的值 
    totalCount = "万手"; 
    maginLeft = left - textGrayPaint.measureText(totalCount) - 5; 
    mCanvas.drawText(totalCount, maginLeft, pillarsChartbottom,textGrayPaint); 
    int pStart = left; 
    float pStartY; 
    double heightScale = (pillarsChartbottom - pillarsChartTop)/maxCount; 
    Paint paint = new Paint(); 
    paint.setAntiAlias(true); 
    paint.setStyle(Paint.Style.FILL); 
    if (flag == StockService.FLAG){ 
      for(MinuteInfo info:minuteInfos){ 
        pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6 
        pStartY = (float) (pillarsChartTop + (maxCount - info.getVolume()) * heightScale); 
        dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2); 
        paint.setColor(info.getColor()); 
        // 画背景图的矩形 
        mCanvas.drawRect(dirty, paint); 
        pStart += per * per56;// 右边的间距 5/6 
      } 
    }else{ 
      for(SingleStockInfo info:infos){ 
        pStart += per * per16;// 每一天实际所占的数据是4/6,加上1/6 
        pStartY = (float) (pillarsChartTop + (maxCount - info.getTotalCount()) * heightScale); 
        dirty = new Rect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2); 
        paint.setColor(info.getColor()); 
        // 画背景图的矩形 
        mCanvas.drawRect(dirty, paint); 
        pStart += per * per56;// 右边的间距 5/6 
      } 
    } 
  } 
/** 
   * 分时图 
   */ 
  @Override 
  public void drawHoursChart(){ 
    double heightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice); 
    int cLeft = left; 
    int cTop = 0; 
    Path path = new Path(); 
    path.moveTo(cLeft, KChartbottom-2); 
    int position = 0; 
    int perPointX = perXPoint[position];// 记录第一条垂直虚线的x坐标 
    for(MinuteInfo info:minuteInfos){ 
      cLeft += per * per16; 
      cTop = (int) (kChartTop + (highPrice - info.getNow()) * heightScale); 
      path.lineTo(cLeft + per * per26, cTop); 
      if (cLeft >= perPointX){ 
        // 恰好画到第一条垂直虚线的地方,需要画下面的时间 
        String text = KChartUtil.getMinute(info.getMinute()); 
        float textWidth = textGrayPaint.measureText(text); 
        int textHeight = (int) (textGrayPaint.descent()- textGrayPaint.ascent()); 
        mCanvas.drawText(text, perPointX - textWidth/2, KChartbottom + textHeight, textGrayPaint); 
        if (!(position == perXPoint.length-1)){ 
          Log.e(TAG, perPointX+"----------"+info.getMinute()+"---"+text); 
          perPointX = perXPoint[++position]; 
        } 
      } 
      cLeft += per * per56;// 右边的间距 5/6 
    } 
    path.lineTo(cLeft, KChartbottom-2); 
    Paint LinePaint = new Paint(); 
    LinePaint.setColor(Color.BLUE); 
    LinePaint.setAntiAlias(true); 
    LinePaint.setStrokeWidth(1); 
    LinePaint.setStyle(Style.STROKE); 
//   LinePaint.setStyle(Style.STROKE); 
    mCanvas.drawPath(path, LinePaint); 
    LinePaint.setAlpha(50); 
    LinePaint.setStyle(Style.FILL); 
    mCanvas.drawPath(path, LinePaint); 
  } 

新年伊始,中国股市走出世界罕见,前无古人后无来者的极端行情,股市有风险,投资需谨慎。
这句话是题外话了,重点还是希望对大家学习Android程序设计有所帮助。


推荐阅读
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • baresip android编译、运行教程1语音通话
    本文介绍了如何在安卓平台上编译和运行baresip android,包括下载相关的sdk和ndk,修改ndk路径和输出目录,以及创建一个c++的安卓工程并将目录考到cpp下。详细步骤可参考给出的链接和文档。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 安卓select模态框样式改变_微软Office风格的多端(Web、安卓、iOS)组件库——Fabric UI...
    介绍FabricUI是微软开源的一套Office风格的多端组件库,共有三套针对性的组件,分别适用于web、android以及iOS,Fab ... [详细]
  • 解决Cydia数据库错误:could not open file /var/lib/dpkg/status 的方法
    本文介绍了解决iOS系统中Cydia数据库错误的方法。通过使用苹果电脑上的Impactor工具和NewTerm软件,以及ifunbox工具和终端命令,可以解决该问题。具体步骤包括下载所需工具、连接手机到电脑、安装NewTerm、下载ifunbox并注册Dropbox账号、下载并解压lib.zip文件、将lib文件夹拖入Books文件夹中,并将lib文件夹拷贝到/var/目录下。以上方法适用于已经越狱且出现Cydia数据库错误的iPhone手机。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Google Play推出全新的应用内评价API,帮助开发者获取更多优质用户反馈。用户每天在Google Play上发表数百万条评论,这有助于开发者了解用户喜好和改进需求。开发者可以选择在适当的时间请求用户撰写评论,以获得全面而有用的反馈。全新应用内评价功能让用户无需返回应用详情页面即可发表评论,提升用户体验。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • Netty源代码分析服务器端启动ServerBootstrap初始化
    本文主要分析了Netty源代码中服务器端启动的过程,包括ServerBootstrap的初始化和相关参数的设置。通过分析NioEventLoopGroup、NioServerSocketChannel、ChannelOption.SO_BACKLOG等关键组件和选项的作用,深入理解Netty服务器端的启动过程。同时,还介绍了LoggingHandler的作用和使用方法,帮助读者更好地理解Netty源代码。 ... [详细]
author-avatar
mobiledu2502876293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有