android 股票 开发,android 股票K線圖

現在在手上的是一個證券資訊類型的app,其中有涉及到股票行情界面,行情中有K線圖等,看到網上很多人在求這方面的資料,所以我特地寫了一個demo在此處給大家分享一下。

下面是做出來的效果圖:

288337b7af37c2f89a9331733a4613f9.png

cd94b304efdd962af0c5f5fad58e6860.png

e6ad0be8a427e62d7b042be96d3d5098.png

這個 界面 是如何畫出來的我就不做介紹了,大家可以去下載項目源碼。

背景圖是利用canvas先畫出一個矩形,然后再畫幾根虛線,均線圖是通過path來繪制的,總之圖的繪制是很簡單的,我就不在這里作介紹了,大家可以去github下載源碼看看。涉及到均線、最高價、最低價、收盤價、開盤價的概念大家可以百度一下。

我再這里要介紹的是計算問題:

大家可以看到分時圖、日K、月K的左邊的成交價格都是不一樣的,而我們的k線都是通過這個價格來繪制的,也就是說價格是時刻變動,那么我們的k線繪制也是變動的。假設我們要計算分時圖中價格為25.69的那一分鍾應該如何畫,畫在屏幕中的哪一個位置,那么這個應該怎么畫呢,價格是變動的,畫的位置也是變動的,但是有一點我們屏幕的大小是不變的。所以我們可以通過背景圖的高度來計算某個價格的線圖應該從哪個地方開始畫。我們可以計算出一個像素點對應多少個價格,分析圖如下:

6b256c0ef4939307ccac7bec59b75861.png

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

所以價格25.69應該是畫在mStartY = (float) (startY+ (highPrice - 25.69) * heightScale);

這個明白了之后其他的原理都是一樣的,我就不介紹了,下面是部分代碼:

@Override

protectedvoiddrawKChatBackGround() {

Rect dirty = newRect(left, kChartTop, right, KChartbottom);

// 畫背景圖的矩形

mCanvas.drawRect(dirty, LineGrayPaint);

PathEffect effects = newDashPathEffect(newfloat[] {5,5,5,5},1);

LineGrayPaint.setPathEffect(effects);

Path path = newPath();

inty = kChartTop +15;

// 畫上面的虛線

path.moveTo(left, y );

path.lineTo(right, y );

String text = getPriceText(highPrice);

inttextHeight = (int) (textGrayPaint.descent() - textGrayPaint.ascent());

mCanvas.drawText(text,left - textGrayPaint.measureText(text) - 5,y + textHeight/2,textGrayPaint);

doublemax = highPrice - lowPrice;

if(max >10){

// 分成四等分

// 畫中間的三根虛線

intn =4;

doublesper = (highPrice - lowPrice) /4;// 每一等分代表的價格

for(inti=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(inti = num -1; i >0; i--) {

intx = left + perWidth * i;

path.moveTo(x, kChartTop);

path.lineTo(x, KChartbottom);

perXPoint[i - 1] = x;

}

mCanvas.drawPath(path, LineGrayPaint);

}

@Override

protectedvoiddrawMAChart() {

// 畫均線

Path path5 = newPath();

Path path10 = newPath();

Path path20 = newPath();

doubleheightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);

intmaStart = left;

floatmaStartY;

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 = newPaint();

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

protectedvoiddrawPillarsChart(intflag) {

LineGrayPaint.setPathEffect(null);

Rect dirty = newRect(left, pillarsChartTop, right, pillarsChartbottom);

// 畫背景圖的矩形

mCanvas.drawRect(dirty, LineGrayPaint);

inty = pillarsChartTop + (pillarsChartbottom - pillarsChartTop)/2;

mCanvas.drawLine(left,y,right, y, LineGrayPaint);

// 中間的值

String totalCount = getPriceText(maxCount/2/10000);

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

intpStart = left;

floatpStartY;

doubleheightScale = (pillarsChartbottom - pillarsChartTop)/maxCount;

Paint paint = newPaint();

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 = newRect(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 = newRect(pStart, (int) pStartY, (int) (pStart + per * per46), pillarsChartbottom-2);

paint.setColor(info.getColor());

// 畫背景圖的矩形

mCanvas.drawRect(dirty, paint);

pStart += per * per56;// 右邊的間距 5/6

}

}

}

/**

* 分時圖

*/

@Override

publicvoiddrawHoursChart(){

doubleheightScale = (KChartbottom - kChartTop)/(highPrice - lowPrice);

intcLeft = left;

intcTop =0;

Path path = newPath();

path.moveTo(cLeft, KChartbottom-2);

intposition =0;

intperPointX = 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());

floattextWidth = textGrayPaint.measureText(text);

inttextHeight = (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 = newPaint();

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

}

demo鏈接:

https://github.com/chuanlongwu/kChart4Android

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值