android 股票行情界面,Android版的股票行情K线图开发

转载请注明出住:http://blog.csdn.net/andywuchuanlong

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

下面是做出来的效果图:

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

这个 界面 是如何画出来的我就不做介绍了,大家可以去下载项目源码。

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

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

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

0818b9ca8b590ca3270a3433284dd417.png

价格和像素形成个一个比例计算是: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

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);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值