先上图:
这里需要理解下,深度图左右两边,绿色代表买部分,红色代表卖部分,买部分从中间到最左边,price依次递减,卖的价格从中间到最右边价格依次递减,纵坐标这里给的是累计的交易量;
理解了要绘制的深度图,我们就可以开始绘制了。
style部分主要主要涉及买卖部分的line ,背景,字体大小,字体颜色等,以及深度图单点以及长按等属性;
直接上代码:
bean十分简单,主要就price和volume两个值,另外为了方便绘制,添加x,y两个坐标值;
public class DepthBean implements Comparable {
private double price;//委托价
private double volume;//委托量
private int tradeType;
private String coinName;
private float xValue;
private float yValue;
public DepthBean(double price, double volume, int tradeType, String coinName) {
this.price = price;
this.volume = volume;
this.tradeType = tradeType;
this.coinName = coinName;
}
public String getCoinName() {
return coinName;
}
public void setCoinName(String coinName) {
this.coinName = coinName;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getVolume() {
return volume;
}
public void setVolume(double volume) {
this.volume = volume;
}
public int getTradeType() {
return tradeType;
}
public void setTradeType(int tradeType) {
this.tradeType = tradeType;
}
public float getxValue() {
return xValue;
}
public void setxValue(float xValue) {
this.xValue = xValue;
}
public float getyValue() {
return yValue;
}
public void setyValue(float yValue) {
this.yValue = yValue;
}
@Override
public int compareTo(@NonNull DepthBean o) {
double diff=this.price-o.price;
if (diff>0){
return 1;
}else if (diff<0){
return -1;
}else{
return 0;
}
}
@Override
public String toString() {
return "DepthBean{price="+price+",volume="+volume+",coinName="+coinName+",tradeType="+tradeType+"}";
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
leftStart=getPaddingLeft()+10;
rightEnd=getMeasuredWidth()-getPaddingRight()-1;
topStart=getPaddingTop()+20;
bottomEnd=getMeasuredHeight() - getPaddingBottom() - 1;
double maxBuyVolume;
double minBuyVolume;
double maxSellVolume;
double minSellVolume;
if (!buyList.isEmpty()){
maxBuyVolume=buyList.get(0).getVolume();
minBuyVolume=buyList.get(buyList.size()-1).getVolume();
}else{
maxBuyVolume=minBuyVolume=0;
}
if (!sellList.isEmpty()){
maxSellVolume=sellList.get(sellList.size()-1).getVolume();
minSellVolume=sellList.get(0).getVolume();
}else{
maxSellVolume=minSellVolume=0;
}
//获得最大最小的交易量的值
maxVolume=Math.max(maxBuyVolume,maxSellVolume);
minVolume=Math.min(minBuyVolume,minSellVolume);
//buylist 不空,取买最低价 ,否则取卖最高价
if (!buyList.isEmpty()){
leftPriceStr=setPrecision(buyList.get(0).getPrice(),priceScale);
}else if (!sellList.isEmpty()){
leftPriceStr=setPrecision(sellList.get(0).getPrice(),priceScale);
}else{
}
//selllist 不空 取卖最低价, 否则取买最高价
if (!sellList.isEmpty()){
rightPriceStr=setPrecision(sellList.get(sellList.size()-1).getPrice(),priceScale);
}else if (!buyList.isEmpty()){
rightPriceStr=setPrecision(buyList.get(buyList.size()-1).getPrice(),priceScale);
}
strokePaint.getTextBounds(leftPriceStr,0,leftPriceStr.length(),textRect);
//深度图除文字外的高度,
depthImgHeight = bottomEnd - topStart - textRect.height() - 18;
avgHeightPerVolume= depthImgHeight / (maxVolume - minVolume);
//x轴每一刻度的值
avgWidthPerSize= (rightEnd - leftStart) / (buyList.size() + sellList.size());
avgVolumeSpace = maxVolume / ordinateNum;
avgOrdinateSpace = depthImgHeight / ordinateNum;
//计算x,y坐标
for (int i=0;i
onlayout中已经计算了所需要的一些数据,这里直接用
//坐标轴,横纵坐标的值
public void drawCoordinate(Canvas canvas){
//横坐标
strokePaint.setStrokeWidth(1);
strokePaint.setColor(abscissaColor);
strokePaint.setTextSize(20);
strokePaint.getTextBounds(rightPriceStr,0,rightPriceStr.length(),textRect);
canvas.drawText(leftPriceStr,leftStart+2,bottomEnd-5,strokePaint);
canvas.drawText(rightPriceStr,rightEnd-textRect.width(),bottomEnd-5,strokePaint);
double centerPrice=0;
if (!buyList.isEmpty()&&!buyList.isEmpty()){
centerPrice= (buyList.get(buyList.size()-1).getPrice()+sellList.get(0).getPrice())/2;
}else if (!buyList.isEmpty()){
centerPrice=buyList.get(buyList.size()-1).getPrice();
}else if (!sellList.isEmpty()){
centerPrice=sellList.get(buyList.size()-1).getPrice();
}
canvas.drawText(setPrecision(centerPrice,priceScale),getMeasuredWidth()/2-30,bottomEnd-5,strokePaint);
//纵坐标
strokePaint.setStrokeWidth(0);
strokePaint.setColor(ordinateColor);
strokePaint.setTextSize(20);
strokePaint.getTextBounds(maxVolume+"",0,(maxVolume+"").length(),textRect);
for (int i=0;i
买部分,根据buyList获取每个点x,y轴数据,y轴相同,
//绘制边线以及背景
private void drawLineAndBg(Canvas canvas){
//左侧买
if (buyList!=null){
linePath.reset();
bgPath.reset();
for (int i=0;i
详情绘制比较简单,主要有两部分判断,第一部分,根据用户点击的位置,获取对应的位置的bean,获得对应的price,x,y等数据;
private float clickDownX;
private float clickDownY;
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
clickDownX=event.getX();
clickDownY=event.getY();
break;
case MotionEvent.ACTION_UP:
float diffX=Math.abs(event.getX()-clickDownX);
float diffY=Math.abs(event.getY()-clickDownY);
if (diffX=(leftStart + (float) avgWidthPerSize * i)&&xValue<(leftStart + (float) avgWidthPerSize * (i+1))){
clickBean=buyList.get(i);
break;
}else if (i==buyList.size()-1&&xValue>= (leftStart + (float) avgWidthPerSize * i)){
clickBean=buyList.get(i);
break;
}
}
}else if (xValue<(leftStart + (float) avgWidthPerSize * buyList.size())){
for (int i=0;i=(leftStart + (float) avgWidthPerSize * i)&&xValue<(leftStart + (float) avgWidthPerSize * (i+1))){
clickBean=buyList.get(i);
break;
}else if (i==buyList.size()-1&&xValue>= (leftStart + (float) avgWidthPerSize * i)&&xValue<(leftStart + (float) avgWidthPerSize * (i+1))){
clickBean=buyList.get(i);
break;
}
}
}else{
for (int i=0;i=sellList.get(i).getxValue()&&xValue= sellList.get(i).getxValue()){
clickBean=sellList.get(i);
break;
}
}
}
}
绘制详情弹框部分,主要绘制基准线,背景框,以及对应的price以及volume等数据;
基准线通过上面onTouchEvent获取的clickBean,从而获取x轴坐标即可绘制。
背景框根据绘制文案的最大宽度+padding与clickbean的x比较确定在基准左右。
//绘制详情信息
public void drawDetailsInfo(Canvas canvas){
if (isShowinfos&&clickBean!=null){
//准线
strokePaint.setStrokeWidth(1);
strokePaint.setTextSize(30);
strokePaint.setColor(sellLineColor);
canvas.drawLine(clickDownX,topStart,clickDownX+2,bottomEnd,strokePaint);
String priceStr="价格: "+setPrecision(clickBean.getPrice(),priceScale);
String volume ="累计交易量:"+setPrecision(clickBean.getVolume(),volumeScale);
strokePaint.setStrokeWidth(1);
strokePaint.setTextSize(30);
strokePaint.setColor(infoTextCol);
strokePaint.getTextBounds(priceStr,0,priceStr.length(),textRect);
float priceStrWidth=textRect.width();
float priceStrHeight=textRect.height();
strokePaint.getTextBounds(volume,0,volume.length(),textRect);
float volumeStrWidth=textRect.width();
float volumeStrHeight=textRect.height();
float maxWidth=Math.max(priceStrWidth,volumeStrWidth);
float maxHeight=Math.max(priceStrHeight,volumeStrHeight);
float bgLeft,bgRight,bgBottom,bgTop;
//根据x坐标判断,绘制的在线的左边还是右边
if (clickBean.getxValue()