代码仓库用~
package com.cxzapp.stamp.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.chengxuanzhang.lib.util.StringUtil;
import com.cxzapp.stamp.modules.user.UserModels;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
/**
* Created by softrice on 15/10/18.
*/
public class OnTimeChartView extends View {
/**
* color
*/
int chartBgColor = 0xFF272727;//图标背景色
int upTextColor = Color.RED;//上升时text的颜色
int defaultTextColor = Color.WHITE;//默认字体颜色
int downTextColor = Color.GREEN;//下降的时候text的颜色
int bordColor = 0xFF333333;//图标边框颜色
int charDivideLineColor = 0xFF333333;//图表分割线颜色
int charBaseDivideLineColor = 0xFF432925;//开盘价分割线颜色
int pathLineColor = 0xFFBFBFBF;//折线的颜色
int hintLineColor = 0xFFFF423D;//点击时 提示线的颜色
/**
* size
*/
int viewHeight;//view 的高度
int viewPadding = 10;//图表边距
int textSize = 12;//字体大小 单位sp
int chartHeight;//图表高度
int leftTextLenght;//左边数字的长度
int rightTextLenght;//右边数字的长度
int textHigh;//text高度
int chartWidth;//图表的宽度
//chart 的上下左右
int top;
int left;
int right;
int bottom;
/**
* paint
*/
Paint textPaint;
Paint linePaint;
/**
* touch 部分
*/
float currentX;//当前点击的x
float currentY;//当前点击的y
long downTime;//手指点击下的时间 毫秒
int intervalTime = 300;//时间间隔 单位 毫秒 点击抬起时间小于该值触发点击事件
TouchListener touchListener;
/**
* data
*/
List stampChartList;
double maxValue = 2999.01;
double minValue = 1320.89;
double openValue;
List xTitle;
final int YValueNum = 3;//从开盘价开始 往上 和 往下 的刻度数目
/**
* time
*/
Calendar c = Calendar.getInstance();
int startTime;
int endTime;
int afternoonTime;
public OnTimeChartView(Context context) {
super(context);
init();
}
public OnTimeChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public OnTimeChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
setBackgroundColor(chartBgColor);
//获取今天的涨跌图 早上9:30 晚上15:00
c.set(Calendar.HOUR_OF_DAY, 9);
c.set(Calendar.MINUTE, 30);
c.set(Calendar.SECOND, 0);
startTime = (int) (c.getTime().getTime() / 1000);
c.set(Calendar.HOUR_OF_DAY, 15);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
endTime = (int) (c.getTime().getTime() / 1000);
c.set(Calendar.HOUR_OF_DAY, 13);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
afternoonTime = (int) (c.getTime().getTime() / 1000);
textPaint = new Paint();
linePaint = new Paint();
textPaint.setAntiAlias(true);
linePaint.setAntiAlias(true);
textPaint.setTextSize(sp2px(textSize));
leftTextLenght = (int) (textPaint.measureText("88888.88") + 0.5);
rightTextLenght = (int) (textPaint.measureText("-10.00") + 0.5);
textHigh = getTextHight(textPaint);
chartHeight = 13 * textHigh;
viewHeight = chartHeight + 2 * textHigh + 2 * viewPadding;
xTitle = new ArrayList<>();
xTitle.add("09:30");
xTitle.add("10:30");
xTitle.add("11:30/13:00");
xTitle.add("14:00");
xTitle.add("15:00");
}
private int getTextHight(Paint paint) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
return (int) (fontMetrics.bottom - fontMetrics.top + 0.5f);
}
/**
* 长度只能match
* 高度只可wrap 和 match
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int specMode = MeasureSpec.getMode(heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, viewHeight);
chartWidth = getWidth() - 2 * viewPadding - leftTextLenght - rightTextLenght;
top = textHigh + viewPadding;
left = viewPadding + leftTextLenght;
right = viewPadding + leftTextLenght + chartWidth;
bottom = textHigh + viewPadding + chartHeight;
}
@Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
drawY(canvas);
drawX(canvas);
drawBorder(canvas);
drawPathLine(canvas);
drawHint(canvas);
}
private void drawHint(Canvas canvas) {
if (currentX == -1 || currentY == -1 || stampChartList == null || stampChartList.size() == 0)
return;
if (!(currentX <= right && currentX >= left && currentY >= top && currentY <= bottom))
return;
DecimalFormat df = new DecimalFormat("0.00");
linePaint.setStrokeWidth(1);
linePaint.setColor(hintLineColor);
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.CENTER);
int position = getDataNum();
if (position != -1) {
UserModels.StampChart chart = stampChartList.get(position);
canvas.drawLine(currentX, top, currentX, bottom, linePaint);
int y = getPriceY(chart.CurPrice);
canvas.drawLine(left, y, right, y, linePaint);
canvas.drawText(StringUtil.formatDate(chart.update_time, "HH:mm"), currentX, viewHeight - viewPadding - textHigh, textPaint);
if (chart.CurPrice >= openValue)
textPaint.setColor(upTextColor);
else
textPaint.setColor(downTextColor);
textPaint.setTextAlign(Paint.Align.LEFT);
canvas.drawText(df.format(chart.CurPrice), viewPadding, y + getTextBottom(textPaint), textPaint);
double valuePercent = (chart.CurPrice - openValue) / openValue * 100;
canvas.drawText(df.format(valuePercent), getWidth() - viewPadding - rightTextLenght, y + getTextBottom(textPaint), textPaint);
canvas.drawText(df.format(chart.CurPrice), viewPadding, y + getTextBottom(textPaint), textPaint);
}
}
private int getDataNum() {
for (int i = 0; i < stampChartList.size(); i++) {
UserModels.StampChart chart = stampChartList.get(i);
if (chart.CurPrice == 0) continue;
if (Math.abs(getTimeX(chart.update_time) - currentX) <= 1) {
return i;
}
}
return -1;
}
private void drawPathLine(Canvas canvas) {
if (stampChartList == null || stampChartList.size() == 0)
return;
linePaint.setStrokeWidth(1);
linePaint.setColor(pathLineColor);
linePaint.setAntiAlias(true);
PointF oldF = new PointF(getTimeX(stampChartList.get(0).update_time), getPriceY((float) openValue));
for (int i = 0; i < stampChartList.size(); i++) {
UserModels.StampChart tmp = stampChartList.get(i);
if (tmp.CurPrice < 0.1)
continue;
int x = (int) getTimeX(tmp.update_time);
int y = (int) getPriceY(tmp.CurPrice);
canvas.drawLine(oldF.x, oldF.y, x, y, linePaint);
oldF.set(x, y);
}
}
private int getPriceY(float curPrice) {
return (int) ((maxValue - curPrice) * 1.0 / (maxValue - minValue) * chartHeight + viewPadding + textHigh);
}
private int getTimeX(int update_time) {
if (update_time > afternoonTime) {
return (int) ((update_time - afternoonTime + 2 * 60 * 60) * 1.0 / (4 * 60 * 60) * (chartWidth) + viewPadding + leftTextLenght);
} else {
return (int) ((update_time - startTime) * 1.0 / (4 * 60 * 60) * (chartWidth) + viewPadding + leftTextLenght);
}
}
private void drawBorder(Canvas canvas) {
linePaint.setStrokeWidth(1);
linePaint.setColor(bordColor);
canvas.drawLine(left, top, right, top, linePaint);
canvas.drawLine(left, bottom, right, bottom, linePaint);
canvas.drawLine(left, top, left, bottom, linePaint);
canvas.drawLine(right, top, right, bottom, linePaint);
// linePaint.setColor(charBaseDivideLineColor);
// canvas.drawLine(left, (top + bottom) / 2, right, (top + bottom) / 2, linePaint);
linePaint.setColor(charDivideLineColor);
int y = chartHeight / YValueNum / 2;
for (int i = 1; i < YValueNum; i++) {
canvas.drawLine(left, (top + bottom) / 2 + y * i, right, (top + bottom) / 2 + y * i, linePaint);
canvas.drawLine(left, (top + bottom) / 2 - y * i, right, (top + bottom) / 2 - y * i, linePaint);
}
int x = chartWidth / (xTitle.size() - 1);
for (int i = 1; i < xTitle.size() - 1; i++) {
canvas.drawLine(left + i * x, top, left + i * x, bottom, linePaint);
}
linePaint.setColor(charBaseDivideLineColor);
linePaint.setStrokeWidth(2);
canvas.drawLine(left, (top + bottom) / 2, right, (top + bottom) / 2, linePaint);
}
private void drawY(Canvas canvas) {
double mid = (maxValue + minValue) / 2;
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.LEFT);
DecimalFormat df = new DecimalFormat("0.00");
canvas.drawText(df.format(mid) + "", viewPadding, viewHeight / 2 + getTextBottom(textPaint), textPaint);
canvas.drawText("0.00", getWidth() - viewPadding - rightTextLenght, viewHeight / 2 + getTextBottom(textPaint), textPaint);
textPaint.setColor(upTextColor);
textPaint.setTextAlign(Paint.Align.LEFT);
for (int i = 1; i <= YValueNum; i++) {
double value = mid + (maxValue - mid) * i / YValueNum;
double valuePercent = (value - openValue) / openValue * 100;
canvas.drawText(df.format(value) + "", viewPadding, viewHeight / 2 - textHigh * 2 * i + getTextBottom(textPaint), textPaint);
canvas.drawText(df.format(valuePercent), getWidth() - viewPadding - rightTextLenght, viewHeight / 2 - textHigh * 2 * i + getTextBottom(textPaint), textPaint);
}
textPaint.setTextAlign(Paint.Align.LEFT);
textPaint.setColor(downTextColor);
for (int i = 1; i <= YValueNum; i++) {
double value = mid - (mid - minValue) * i / YValueNum;
double valuePercent = (value - openValue) / openValue * 100;
canvas.drawText(df.format(value) + "", viewPadding, viewHeight / 2 + textHigh * 2 * i + getTextBottom(textPaint), textPaint);
canvas.drawText(df.format(valuePercent), getWidth() - viewPadding - rightTextLenght, viewHeight / 2 + textHigh * 2 * i + getTextBottom(textPaint), textPaint);
}
}
private int getTextBottom(Paint textPaint) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
return (int) fontMetrics.bottom;
}
private int getTextTop(Paint textPaint) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
return (int) fontMetrics.top;
}
private void drawX(Canvas canvas) {
DecimalFormat df = new DecimalFormat("0.00");
textPaint.setTextAlign(Paint.Align.CENTER);
textPaint.setColor(defaultTextColor);
for (int i = 0; i < xTitle.size(); i++) {
canvas.drawText(xTitle.get(i), viewPadding + leftTextLenght + chartWidth / 4 * i, viewHeight - viewPadding, textPaint);
}
textPaint.setTextAlign(Paint.Align.LEFT);
if (stampChartList != null && stampChartList.size() > 0) {
double value = stampChartList.get(stampChartList.size() - 1).CurPrice;
canvas.drawText("最新" + df.format(value), viewPadding + leftTextLenght, viewPadding - getTextTop(textPaint), textPaint);
int len = (int) textPaint.measureText("最新" + "19488.67");
double dis = value - openValue;
double disPercent = dis / openValue * 100;
if (value < openValue) {
textPaint.setColor(downTextColor);
canvas.drawText(" ↓" + df.format(dis) + "(" + df.format(disPercent) + "%)", viewPadding + leftTextLenght + len, viewPadding - getTextTop(textPaint), textPaint);
} else {
textPaint.setColor(upTextColor);
canvas.drawText(" ↑" + df.format(dis) + "(" + df.format(disPercent) + "%)", viewPadding + leftTextLenght + len, viewPadding - getTextTop(textPaint), textPaint);
}
} else {
canvas.drawText("最新-- --(--)", viewPadding + leftTextLenght, viewPadding - getTextTop(textPaint), textPaint);
}
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.RIGHT);
canvas.drawText("涨跌幅(%)", getWidth() - rightTextLenght - viewPadding, viewPadding - getTextTop(textPaint), textPaint);
}
public void setStampChartList(List stampChartList) {
this.stampChartList = stampChartList;
openValue = 0;
maxValue = Double.MIN_VALUE;
minValue = Double.MAX_VALUE;
if (stampChartList != null) {
for (int i = 0; i < stampChartList.size(); i++) {
double curPrice = stampChartList.get(i).CurPrice;
if (curPrice == 0)
continue;
if (openValue == 0)
openValue = curPrice;
maxValue = maxValue > curPrice ? maxValue : curPrice;
minValue = minValue < curPrice ? minValue : curPrice;
}
} else {
return;
}
double dis = Math.max(maxValue - openValue, openValue - minValue);
dis += 5;
maxValue = openValue + dis;
minValue = openValue - dis;
this.postInvalidate();
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(event);
Calendar c = Calendar.getInstance();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
currentX = -1;
currentY = -1;
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
if (judgeDownOrUp(x, y)) {
currentX = -1;
currentY = -1;
getParent().requestDisallowInterceptTouchEvent(false);
} else {
getParent().requestDisallowInterceptTouchEvent(true);
currentX = event.getX();
currentY = event.getY();
}
break;
case MotionEvent.ACTION_DOWN:
downTime = c.getTimeInMillis() ;
currentX = event.getX();
currentY = event.getY();
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Calendar c = Calendar.getInstance();
long upTime = c.getTimeInMillis();
if (upTime - downTime <= intervalTime) {
if (touchListener != null) {
touchListener.click();
}
} else {
getParent().requestDisallowInterceptTouchEvent(false);
}
currentX = -1;
currentY = -1;
break;
}
postInvalidate();
return super.onTouchEvent(event);
}
private boolean judgeDownOrUp(float x, float y) {
if (Math.abs(currentX - x) + 10 < Math.abs(currentY - y)) {
return true;
} else {
return false;
}
}
public int sp2px(float spValue) {
final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
public void setTouchListener(TouchListener touchListener) {
this.touchListener = touchListener;
}
public void setMaxValue(double maxValue) {
this.maxValue = maxValue;
}
public void setMinValue(double minValue) {
this.minValue = minValue;
}
public interface TouchListener {
void click();
}
}
package com.cxzapp.stamp.ui;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.chengxuanzhang.lib.util.StringUtil;
import com.cxzapp.stamp.modules.user.UserModels;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;
/**
* Created by softrice on 15/10/19.
*/
public class CandleSticksChartView extends View {
/**
* 回调接口
*/
public interface TouchListener {
void click();
}
/**
* color
*/
int MA5Color = Color.WHITE;
int MA10Color = 0xFFD57123;
int Ma20Color = 0xFFCB37CA;
int chartBgColor = 0xFF272727;//图标背景色
int upTextColor = Color.RED;//上升时text的颜色
int defaultTextColor = Color.WHITE;//默认字体颜色
int downTextColor = Color.GREEN;//下降的时候text的颜色
int bordColor = 0xFF333333;//图标边框颜色
int charDivideLineColor = 0xFF333333;//图表分割线颜色
int hintLineColor = 0xFFFF423D;//
/**
* size
*/
int viewHeight;//view 的高度
int viewPadding = 10;//图表边距
int textSize = 12;//字体大小 单位sp
int chartHeight;//图表高度
int leftTextLenght;//左边数字的长度
int textHigh;//text高度
int chartWidth;//图表的宽度
int defaultStickWidth = 20;
int stickWidth = defaultStickWidth;// 蜡烛宽度
int hintBorderWidth;//详情框宽度
int hintBorderLeftTextWidth;//详情框左边蚊子宽度
int hintBorderPadding = 10;
//chart 的上下左右
int top;
int left;
int right;
int bottom;
/**
* paint
*/
Paint textPaint;
Paint linePaint;
/**
* touch 部分
*/
float currentX;//当前点击的x
float currentY;//当前点击的y
long downTime;//手指点击下的时间
int intervalTime = 300;//时间间隔 单位 毫秒 点击抬起时间小于该值触发点击事件
TouchListener touchListener;
/**
* data
*/
List stampInfoList;
double maxValue = 2000;
double minValue = 1000;
final int YValueNum = 7;//Y轴的刻度个数
int XValueNum = 5;//X轴刻度个数
int XDay = 10;
double MA5 = -1, MA10 = -1, MA20 = -1;
/**
* time
*/
Calendar c = Calendar.getInstance();
int startTime;
int endTime;
DecimalFormat df;
public CandleSticksChartView(Context context) {
super(context);
init();
}
public CandleSticksChartView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CandleSticksChartView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
df = new DecimalFormat("0.00");
setBackgroundColor(chartBgColor);
textPaint = new Paint();
linePaint = new Paint();
textPaint.setAntiAlias(true);
linePaint.setAntiAlias(true);
textPaint.setTextSize(sp2px(textSize));
leftTextLenght = (int) (textPaint.measureText("88888.88") + 0.5);
textHigh = getTextHight(textPaint);
chartHeight = 13 * textHigh;
viewHeight = chartHeight + 2 * textHigh + 2 * viewPadding;
hintBorderLeftTextWidth = (int) (textPaint.measureText("日期: ") + 0.5);
hintBorderWidth = (int) (textPaint.measureText("日期:20150518") + 0.5);
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
super.dispatchTouchEvent(event);
Calendar c = Calendar.getInstance();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
currentX = -1;
currentY = -1;
break;
case MotionEvent.ACTION_MOVE:
float x = event.getX();
float y = event.getY();
if (judgeDownOrUp(x, y)) {
currentX = -1;
currentY = -1;
getParent().requestDisallowInterceptTouchEvent(false);
} else {
getParent().requestDisallowInterceptTouchEvent(true);
currentX = event.getX();
currentY = event.getY();
}
break;
case MotionEvent.ACTION_DOWN:
downTime = c.getTimeInMillis();
currentX = event.getX();
currentY = event.getY();
break;
}
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
Calendar c = Calendar.getInstance();
long upTime = c.getTimeInMillis();
if (upTime - downTime <= intervalTime) {
if (touchListener != null) {
touchListener.click();
}
} else {
getParent().requestDisallowInterceptTouchEvent(false);
}
currentX = -1;
currentY = -1;
break;
}
postInvalidate();
return super.onTouchEvent(event);
}
@Override
protected void onDraw(Canvas canvas) {
drawMA(canvas);
drawY(canvas);
drawX(canvas);
drawBorder(canvas);
drawCandleSticks(canvas);
drawHint(canvas);
}
private void drawY(Canvas canvas) {
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.LEFT);
double disY = (float) ((maxValue - minValue) / (YValueNum - 1));
for (int i = 0; i < YValueNum; i++) {
double value = disY * i + minValue;
canvas.drawText(df.format(value), viewPadding, (float) ((maxValue - value) / (maxValue - minValue) * chartHeight + viewPadding + textHigh + getTextBottom(textPaint)), textPaint);
}
}
private void drawX(Canvas canvas) {
if (stampInfoList == null || stampInfoList.size() == 0)
return;
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.RIGHT);
for (int i = 0; i <= XValueNum; i++) {
int time = startTime + i * XDay * 24 * 60 * 60;
canvas.drawText(StringUtil.formatDate(time, "MMdd"),
left + chartWidth / (XValueNum - 1) * i, viewHeight - viewPadding, textPaint);
}
int len5 = (int) textPaint.measureText("MA5:88888.88");
textPaint.setColor(MA5Color);
textPaint.setTextAlign(Paint.Align.LEFT);
if (MA5 == -1)
canvas.drawText("MA5:--", left, viewPadding - getTextTop(textPaint), textPaint);
else
canvas.drawText("MA5:" + df.format(MA5), left, viewPadding - getTextTop(textPaint), textPaint);
int len10 = (int) textPaint.measureText("MA10:88888.88");
textPaint.setColor(MA10Color);
if (MA10 == -1)
canvas.drawText("MA10:--", left + len5, viewPadding - getTextTop(textPaint), textPaint);
else
canvas.drawText("MA10:" + df.format(MA10), left + len5, viewPadding - getTextTop(textPaint), textPaint);
textPaint.setColor(Ma20Color);
if (MA20 == -1)
canvas.drawText("MA20:--", left + len5 + len10, viewPadding - getTextTop(textPaint), textPaint);
else
canvas.drawText("MA20:" + df.format(MA20), left + len5 + len10, viewPadding - getTextTop(textPaint), textPaint);
}
private void drawBorder(Canvas canvas) {
linePaint.setStrokeWidth(1);
linePaint.setColor(bordColor);
canvas.drawLine(left, top, right, top, linePaint);
canvas.drawLine(left, bottom, right, bottom, linePaint);
canvas.drawLine(left, top, left, bottom, linePaint);
canvas.drawLine(right, top, right, bottom, linePaint);
linePaint.setColor(charDivideLineColor);
double disY = (maxValue - minValue) / (YValueNum - 1);
for (int i = 1; i <= YValueNum - 1; i++) {
double value = disY * i + minValue;
int y = (int) (viewPadding + textHigh + (maxValue - value) / (maxValue - minValue) * chartHeight);
canvas.drawLine(left, y, right, y, linePaint);
}
double disX = chartWidth * 1.0 / (XValueNum - 1);
for (int i = 1; i < XValueNum - 1; i++) {
int x = (int) (i * disX + left);
canvas.drawLine(x, top, x, bottom, linePaint);
}
}
private void drawCandleSticks(Canvas canvas) {
if (stampInfoList == null || stampInfoList.size() == 0)
return;
int disX = getTimeX(stampInfoList.get(0).update_time + 24 * 60 * 60) - getTimeX(stampInfoList.get(0).update_time);
if (disX < defaultStickWidth) {
stickWidth = disX;
} else {
stickWidth = defaultStickWidth;
}
for (int i = 0; i < stampInfoList.size(); i++) {
int high, low, open, close;
int centerX;
UserModels.StampInfo info = stampInfoList.get(i);
high = getPriceY(info.HighPrice);
low = getPriceY(info.LowPrice);
open = getPriceY(info.OpenPrice);
close = getPriceY(info.YesterBalancePrice);
centerX = getTimeX(info.update_time);
Rect rect = new Rect();
disX = 20;
if (info.OpenPrice < info.YesterBalancePrice) {
linePaint.setColor(upTextColor);
rect.set(centerX - disX / 2, close, centerX + disX / 2, open);
canvas.drawRect(rect, linePaint);
} else {
linePaint.setColor(downTextColor);
rect.set(centerX - disX / 2, open, centerX + disX / 2, close);
canvas.drawRect(rect, linePaint);
}
linePaint.setStrokeWidth(1);
canvas.drawLine(centerX, high, centerX, low, linePaint);
}
}
private void drawMA(Canvas canvas) {
if (stampInfoList == null || stampInfoList.size() == 0)
return;
if (stampInfoList.size() < 5)
return;
//MA5
MA5 = 0;
linePaint.setColor(MA5Color);
linePaint.setStrokeWidth(2);
linePaint.setTextAlign(Paint.Align.LEFT);
double ave = 0;
for (int i = 0; i < 5; i++) {
UserModels.StampInfo info = stampInfoList.get(i);
ave += info.YesterBalancePrice;
}
ave /= 5;
int oldx, oldy;
oldy = getPriceY((float) ave);
oldx = getTimeX(stampInfoList.get(4).update_time);
for (int i = 5; i < stampInfoList.size(); i++) {
ave = 0;
for (int j = 0; j < 5; j++) {
UserModels.StampInfo info = stampInfoList.get(i - j);
ave += info.YesterBalancePrice;
}
ave /= 5;
MA5 += ave;
int y = getPriceY((float) ave);
int x = getTimeX(stampInfoList.get(i).update_time);
canvas.drawLine(oldx, oldy, x, y, linePaint);
oldx = x;
oldy = y;
}
MA5 /= stampInfoList.size() - 4;
//MA10
if (stampInfoList.size() < 10)
return;
MA10 = 0;
linePaint.setColor(MA10Color);
ave = 0;
for (int i = 0; i < 10; i++) {
UserModels.StampInfo info = stampInfoList.get(i);
ave += info.YesterBalancePrice;
}
ave /= 10;
oldy = getPriceY((float) ave);
oldx = getTimeX(stampInfoList.get(9).update_time);
for (int i = 10; i < stampInfoList.size(); i++) {
ave = 0;
for (int j = 0; j < 10; j++) {
UserModels.StampInfo info = stampInfoList.get(i - j);
ave += info.YesterBalancePrice;
}
ave /= 10;
MA10 += ave;
int y = getPriceY((float) ave);
int x = getTimeX(stampInfoList.get(i).update_time);
canvas.drawLine(oldx, oldy, x, y, linePaint);
oldx = x;
oldy = y;
}
MA10 /= stampInfoList.size() - 9;
//MA20
if (stampInfoList.size() < 20)
return;
MA20 = 0;
linePaint.setColor(MA10Color);
ave = 0;
for (int i = 0; i < 20; i++) {
UserModels.StampInfo info = stampInfoList.get(i);
ave += info.YesterBalancePrice;
}
ave /= 20;
oldy = getPriceY((float) ave);
oldx = getTimeX(stampInfoList.get(19).update_time);
for (int i = 20; i < stampInfoList.size(); i++) {
ave = 0;
for (int j = 0; j < 20; j++) {
UserModels.StampInfo info = stampInfoList.get(i - j);
ave += info.YesterBalancePrice;
}
ave /= 20;
MA20 += ave;
int y = getPriceY((float) ave);
int x = getTimeX(stampInfoList.get(i).update_time);
canvas.drawLine(oldx, oldy, x, y, linePaint);
oldx = x;
oldy = y;
}
MA20 /= stampInfoList.size() - 19;
}
private void drawHint(Canvas canvas) {
if (currentX == -1 || currentY == -1 || stampInfoList == null || stampInfoList.size() == 0)
return;
if (!(currentX <= right && currentX >= left && currentY >= top && currentY <= bottom))
return;
linePaint.setStrokeWidth(1);
linePaint.setColor(hintLineColor);
textPaint.setColor(defaultTextColor);
textPaint.setTextAlign(Paint.Align.CENTER);
int position = getDataNum();
if (position != -1) {
UserModels.StampInfo info = stampInfoList.get(position);
canvas.drawLine(getTimeX(info.update_time), top, getTimeX(info.update_time), bottom, linePaint);
drawHintDetail(canvas, position);
}
}
private void drawHintDetail(Canvas canvas, int position) {
// 绘制点击线条及详情区域
UserModels.StampInfo info = stampInfoList.get(position);
linePaint.setColor(Color.BLACK);
linePaint.setAlpha(150);
int borderLeft, borderRight, borderTop, borderBottom;
if (getTimeX(info.update_time) > left + chartWidth * 1.0 / 2) {
borderLeft = left;
borderRight = left + hintBorderWidth + 2 * hintBorderPadding;
borderTop = top;
borderBottom = top + textHigh * 5 + 2 * hintBorderPadding;
} else {
borderLeft = right - (hintBorderWidth + 2 * hintBorderPadding);
borderRight = right;
borderTop = top;
borderBottom = top + textHigh * 5 + 2 * hintBorderPadding;
}
canvas.drawRect(borderLeft, borderTop, borderRight, borderBottom, linePaint);
textPaint.setTextAlign(Paint.Align.LEFT);
try {
canvas.drawText("日期: " + StringUtil.formatDate(info.update_time, "yyyyMMdd"), borderLeft + hintBorderPadding, borderTop + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("开盘: ", borderLeft + hintBorderPadding, borderTop + textHigh * 1.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("收盘: ", borderLeft + hintBorderPadding, borderTop + textHigh * 2.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("最高: ", borderLeft + hintBorderPadding, borderTop + textHigh * 3.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("最低: ", borderLeft + hintBorderPadding, borderTop + textHigh * 4.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
if (info.OpenPrice < info.YesterBalancePrice) {
textPaint.setColor(upTextColor);
} else {
textPaint.setColor(downTextColor);
}
canvas.drawText(df.format(info.OpenPrice), borderLeft + hintBorderPadding + hintBorderLeftTextWidth, borderTop + textHigh * 1.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText(df.format(info.YesterBalancePrice), borderLeft + hintBorderPadding + hintBorderLeftTextWidth, borderTop + textHigh * 2.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText(df.format(info.HighPrice), borderLeft + hintBorderPadding + hintBorderLeftTextWidth, borderTop + textHigh * 3.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText(df.format(info.LowPrice), borderLeft + hintBorderPadding + hintBorderLeftTextWidth, borderTop + textHigh * 4.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
} catch (Exception e) {
canvas.drawText("日期: -- --", borderLeft + hintBorderPadding, borderTop + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("开盘: -- --", borderLeft + hintBorderPadding, borderTop + textHigh * 1.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("收盘: -- --", borderLeft + hintBorderPadding, borderTop + textHigh * 2.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("最高: -- --", borderLeft + hintBorderPadding, borderTop + textHigh * 3.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
canvas.drawText("最低: -- --", borderLeft + hintBorderPadding, borderTop + textHigh * 4.0f + hintBorderPadding - getTextTop(textPaint), textPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthMeasureSpec, viewHeight);
chartWidth = getWidth() - 2 * viewPadding - leftTextLenght;
top = textHigh + viewPadding;
left = viewPadding + leftTextLenght;
right = getWidth() - viewPadding;
bottom = textHigh + viewPadding + chartHeight;
}
private boolean judgeDownOrUp(float x, float y) {
if (Math.abs(currentX - x) + 10 < Math.abs(currentY - y)) {
return true;
} else {
return false;
}
}
private int getTextBottom(Paint textPaint) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
return (int) fontMetrics.bottom;
}
private int getTextTop(Paint textPaint) {
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
return (int) fontMetrics.top;
}
private int getPriceY(float curPrice) {
return (int) ((maxValue - curPrice) * 1.0 / (maxValue - minValue) * chartHeight + viewPadding + textHigh);
}
private int getTimeX(int update_time) {
return (int) ((update_time - startTime) * 1.0 / (endTime - startTime) * chartWidth + leftTextLenght + viewPadding);
}
public void setTouchListener(TouchListener touchListener) {
this.touchListener = touchListener;
}
public int sp2px(float spValue) {
final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}
private int getDataNum() {
for (int i = 0; i < stampInfoList.size(); i++) {
UserModels.StampInfo info = stampInfoList.get(i);
if (Math.abs(getTimeX(info.update_time) - currentX) < stickWidth) {
return i;
}
}
return -1;
}
private int getTextHight(Paint paint) {
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
return (int) (fontMetrics.bottom - fontMetrics.top + 0.5f);
}
public void setStampInfoList(List stampInfoList) {
this.stampInfoList = stampInfoList;
if (stampInfoList == null || stampInfoList.size() == 0)
return;
maxValue = Float.MIN_VALUE;
minValue = Float.MAX_VALUE;
for (int i = 0; i < stampInfoList.size(); i++) {
UserModels.StampInfo info = stampInfoList.get(i);
maxValue = maxValue > info.HighPrice ? maxValue : info.HighPrice;
minValue = minValue < info.LowPrice ? minValue : info.LowPrice;
minValue = minValue < info.YesterBalancePrice ? minValue : info.YesterBalancePrice;
minValue = minValue < info.OpenPrice ? minValue : info.OpenPrice;
maxValue = maxValue > info.OpenPrice ? maxValue : info.OpenPrice;
maxValue = maxValue > info.YesterBalancePrice ? maxValue : info.YesterBalancePrice;
}
startTime = stampInfoList.get(0).update_time;
startTime -= 24 * 60 * 60;
endTime = stampInfoList.get(stampInfoList.size() - 1).update_time;
if (startTime - endTime < 40 * 24 * 60 * 60) {
XValueNum = 5;
XDay = 10;
} else {
XValueNum = (startTime - endTime) / (10 * 24 * 60 * 60) + 2;
XDay = 10;
}
endTime = startTime + (XValueNum - 1) * XDay * 24 * 60 * 60;
this.postInvalidate();
}
}