k线相关-深度图篇

先上图:

k线相关-深度图篇_第1张图片

这里需要理解下,深度图左右两边,绿色代表买部分,红色代表卖部分,买部分从中间到最左边,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+"}";
    }
}

 

onlayout

 @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()

 

github地址

你可能感兴趣的:(自定义view,android)