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<n;i++){
        y = i*((KChartbottom - kChartTop)/n) + kChartTop;
        path.moveTo(left, y);
        path.lineTo(right,y);
        text = getPriceText(highPrice - i*sper);
        mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
      }
    }else{
      // 分成两等分
      // 画中间的虚线
      y = (KChartbottom - kChartTop)/2 + kChartTop;
      path.moveTo(left, y);
      path.lineTo(right, y);
      text = getPriceText(highPrice - (highPrice - lowPrice) / 2);
      mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
    }
    // 画下面的虚线
    y = KChartbottom - 15;
    path.moveTo(left, y);
    path.lineTo(right, y);
    text = getPriceText(lowPrice);
    mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);
//   // 画等分的虚线和下面的日期
    for (int i = num - 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程序设计有所帮助。

(0)

相关推荐

  • Android获取应用程序名称(ApplicationName)示例

    MainActivity如下: 复制代码 代码如下: package cn.testapplicationname; import android.os.Bundle; import android.widget.TextView; import android.app.Activity; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; /** * Demo描述: * 获取应

  • 一看就懂的Android APP开发入门教程

    工作中有做过手机App项目,前端和android或ios程序员配合完成整个项目的开发,开发过程中与ios程序配合基本没什么问题,而android各种机子和rom的问题很多,这也让我产生了学习android和ios程序开发的兴趣.于是凌晨一点睡不着写了第一个android程序HelloAndroid,po出来分享给其他也想学习android开发的朋友,这么傻瓜的Android开发入门文章,有一点开发基础的应该都能看懂. 一.准备工作 主要以我自己的开发环境为例,下载安装JDK和Android SD

  • ANDROID 完美退出APP的实例代码

    大家都知道 Android 的 Activity 是存着历史栈的,比如从 A -> B -> C,C 完成 finish 后回到 B,把所有的Activity 都 finish了,程序就自然退出了. 当然在 finish 的同时也需要是否自己程序的其他资源.所以需要想个办法把 Activity 给存起来.然后在程序退出的地方调用它们的 finish()方法. 使用全局变量.对了,第一个想到的就是继承 Application,代码入下: 复制代码 代码如下: public class Agent

  • 怎么发布打包并发布自己的Android应用(APP)

    第一步,在Eclipse中选择需要打包的项目,然后右键--选择Export,会弹出一个打包的提示框,如下图所示. 按Next之后,会继续出现一个提示框,这里你可以选择自己需要打包的项目(默认是刚才选中的)如下图: 按Next之后,会弹出一个关于"Keystore"的提示,选择"Create new Keystore",并浏览.选择签名文件要保存的路径, (关于Keystore的原理.作用等这里暂时不细说,请大家发布前务必保存好该签名文件,非常重要的.) 如下图所示:

  • Android开发中避免应用无响应的方法(Application Not Responding、ANR)

    App里发生的最糟糕的事是弹出应用无响应"Application Not Responding" (ANR) 对话框.本课讲的是如何保持应用响应,避免ANR. 什么触发ANR 通常,系统会在应用无法对用户输入响应时显示ANR.比如,如果一个应用在I/O操作上阻塞了(频繁请求网络)UI线程,系统无法处理用户输入事件.或者,在UI线程中,app花了大量时间在构建复杂的类,或在游戏中计算下一个动作.保证这些操作高效是很重要的,但最高效的代码也需要花费时间. 在任何情况下,都不要在UI线程执行

  • Android 应用APP加入聊天功能

    简介 自去年 LeanCloud 发布实时通信(IM)服务之后,基于用户反馈和工程师对需求的消化和对业务的提炼,上周正式发布了「实时通信 2.0 」.设计理念依然是「灵活.解耦.可组合.可定制」,具体可以参考<实时通信开发指南>,了解 LeanCloud 实时通信的基本概念和模型. 下载和安装 可以到 LeanCloud 官方下载点下载 LeanCloud IM SDK v2 版本.将下载到的 jar 包加入工程即可. 一对一的文本聊天 我们先从最简单的环节入手,看看怎么用 LeanCloud

  • android实现通知栏下载更新app示例

    1.设计思路,使用VersionCode定义为版本升级参数.android为我们定义版本提供了2个属性: 复制代码 代码如下: <manifest package="com.cnblogs.tianxia.subway"android:versionCode="1" <!--Integer类型,系统不显示给用户-->android:versionName="1.0"<!--String类型,系统显示用户-->>

  • 通过Html网页调用本地安卓(android)app程序代码

    一.通过html页面打开Android本地的app 1.首先在编写一个简单的html页面 复制代码 代码如下: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <a h

  • Android 避免APP启动闪黑屏的解决办法(Theme和Style)

    前几天Boss就反应说,机器每次启动程序都会闪一下黑屏,这个客户不接受.没办法,只能想想怎么解决,最后找到了下面的方法.闪黑屏的原因主要是我们启动Activity的时候,需要跑完onCreate和onResume才会显示界面.也就是说需要处理一些数据后,才会显示.按照这种思路,是不是我把初始化的工作尽量减少就可以避免黑屏?事实是,就算你onCreate啥都不做,仍然会闪一下黑屏,因为初始化解析界面时需要一定时间.下面是解决办法:1.自定义Theme 复制代码 代码如下: 设置背景图Theme<s

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

    现在在手上的是一个证券资讯类型的app,其中有涉及到股票行情界面,行情中有K线图等,看到网上很多人在求这方面的资料,所以我特地写了一个demo在此处给大家分享一下. 下面是做出来的效果图: 背景图是利用canvas先画出一个矩形,然后再画几根虚线,均线图是通过path来绘制的,总之图的绘制是很简单的,我就不在这里作介绍了,大家可以去github下载源码看看.涉及到均线.最高价.最低价.收盘价.开盘价的概念大家可以百度一下. 我再这里要介绍的是计算问题: 大家可以看到分时图.日K.月K的左边的成交

  • 使用PyQtGraph绘制精美的股票行情K线图的示例代码

    pyqtgraph是Python平台上一种功能强大的2D/3D绘图库,相对于matplotlib库,由于其在内部实现方式上,使用了高速计算的numpy信号处理库以及Qt的GraphicsView框架,因此它在大数据量的处理及快速显示方面有着天然的优势,非常适合于需要快速绘图更新.视频或实时交互性的操作场合,在数学.科学和工程领域都有着广泛的应用. K线图介绍 对于股票交易者来讲,K线图是弄清股票一段时间走势的一种最基本的图形工具,K线分为阳线和阴线,阳线和阴线都包含了开盘价.收盘价.最高价和最低

  • python爬虫爬取股票的k线图

    目录 前言 数据来源分析 数据抓取 总结 前言 之前已经讲述了一些关于 python 获取基金的一些信息,最近又有了一些新发现,和大家分享一下,这个是非常重要的内容,非常重要的内容.这个数据也是非常的敏感,在一些搞量化交易的平台上,这些数据都是要收费的,而且数据的质量也不能保障.这个内容就是如何获取股票交易的 k 线数据. 数据来源分析 我是非常欣赏东方某富的,因为同为券商,和别的公司确实不大一样,有这互联网的基因,可以这样说,是因为它的出现改变了一些行业的规则.话不多说,这里以海尔智家为例,抓

  • 使用Python画股票的K线图的方法步骤

    导言 本文简单介绍了如何从网易财经获取某支股票的价格数据,并根据价格数据画出相应的日K线图.有助于新手了解并使用Python的相关功能.包括列表.自定义函数.for循环.if函数以及如何使用matplotlib进行作图等内容. 第一步:从网易财经获取股票的价格数据 我一般是在网易财经查看某支股票的价格和成交数据,网易财经可以查到任意沪深的股票,我们使用招商银行的数据作为参考. 1.构建爬虫获取股票价格数据 这里不对Python做介绍了,如果需要了解什么是Python,可以自行百度或者访问Pyth

  • 利用python numpy+matplotlib绘制股票k线图的方法

    一.python numpy + matplotlib 画股票k线图 # -- coding: utf-8 -- import requests import numpy as np from matplotlib import pyplot as plt from matplotlib import animation fig = plt.figure(figsize=(8,6), dpi=72,facecolor="white") axes = plt.subplot(111) a

  • Python+Tkinter实现股票K线图的绘制

    目录 子窗口 子窗口框架 绘制K线图 在前面的文章中,我们一起学习了如何通过 Python 抓取东方财富网的实时股票数据以及如何制作成 Tkinter GUI 程序,链接如下 用 Python 爬取股票实时数据 Tkinter制作股票数据抓取小程序,有点秀! 今天我们就在这个基础上,在 Tkinter 程序中绘制 K 线图,一起来看看吧 子窗口 我们今天的整体代码还是基于上次的 Tkinter 股票程序,在主类 MainCreator 下面创建一个函数 create_subwindow     

  • 基于Python轻松制作一个股票K线图网站

    目录 获取股票数据 PyEcharts 作图 构建 Web 框架 视图函数编写 模板编写 编辑主逻辑 前端页面编写 在前面的文章中,我们学习了如何使用 Tkinter 构建股票数据抓取以及展示K线图功能,虽然大致的功能已经具备,但是在当今这个人手一个 Web 服务的年代,GUI 程序还是没有 Web 服务来的香啊. 我们需要用到的知识包括 PyEcharts 的使用,tushare 库获取股票数据的方法以及 Flask 的基本用法. 获取股票数据 我们先来看下 tushare 的使用,这个应该是

  • Python绘制专业的K线图 源代码解析

    目录 1.股票数据 2.数据处理 3.绘制K线 4.去除图中非交易日 5.在K线图中,添加成交量 K线图简介: K线图又被成为"蜡烛图"."阴阳线"等,它在视觉效果上可以很清晰得凸显出市场多空形势,K线图成为大家查看行情数据以及各式量化分析不可或缺的一环.在K线图常见的时间跨度分钟.日.周以及月. K线由高开低收四个价格绘制而成.分为阳线与阴线两种,收盘价高于开盘价时为阳线,收盘价低于开盘价时为阴线:K线图的示意图如下: K线由矩形实体与上下两根影线组成,实体上方的

  • Python绘制K线图之可视化神器pyecharts的使用

    K线图 概念 股市及期货市bai场中的K线图的du画法包含四个zhi数据,即开盘dao价.最高价.最低价zhuan.收盘价,所有的shuk线都是围绕这四个数据展开,反映大势的状况和价格信息.如果把每日的K线图放在一张纸上,就能得到日K线图,同样也可画出周K线图.月K线图.研究金融的小伙伴肯定比较熟悉这个,那么我们看起来比较复杂的K线图,又是这样画出来的,本文我们将一起探索K线图的魅力与神奇之处吧! K线图 用处 K线图用处于股票分析,作为数据分析,以后的进入大数据肯定是一个趋势和热潮,K线图的专

  • 利用Matlab绘制优美的k线图

    目录 效果 代码 效果一 极光 效果二 暖调 效果三 黑白 本期又是一个花里胡哨的数据可视化,前两天刷到了耐克的视觉设计师Gladys Orteza绘制的k线图作品,把沉闷的股票图变成了精彩的风景,但是那些大部分是真的完全看不清,我这里挑选了几个能看清的k线图风格将其用MATLAB进行了实现. 效果 代码 代码中使用的数据 SimulatedStock.mat 是MATLAB自带的示例数据,因此不需要下载,不过要绘制k线图,仍需安装Financial Toolbox工具箱. 效果一 极光 % @

随机推荐