学习自定义 —— 自定义线型图控件

自定义控件篇:

                                                      自定义折线图

前言:自定义控件永远都是客户端开发的一个必须攻破的难题

首先得了解需要实现的样式,确定有没有可继承的控件类,若没有就直接继承View。

View也有自己的生命周期,先了解下我们常用的几个自定义View方法:

构造方法  -  onMeasure - onLayout - onDraw -  onTouchEvent - onAnimationStart

在构造方法里进行画图工具和数据的初始化

        srceenWidth = Tool.getWidth(context);
        srceenHeight = Tool.getHeight(context);
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true); //去锯齿
        paint.setStrokeWidth(2);
        paint.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        paint.setColor(context.getResources().getColor(R.color._7C7F99));

        String text = "08-06";
        Rect rect = new Rect();
        paint.getTextBounds(text,0,text.length(), rect);
        textheight = rect.height();
        textWidth = rect.width();

        int srceenHeightpf = srceenHeight/100;
        YPoint = Tool.dpToPx(10);
        YLength = srceenHeightpf*PriceShjListKinView.Ypinf -YPoint;//K线高度缩小给上下留白
        YPoint = YPoint -(YPoint/2);//上下各一半
        YScale = YLength/YScalenum;//Y轴均分

在onMeasure方法里对View的高度和宽度做屏幕适配

setMeasuredDimension(srceenWidth, Tool.getHeight(context)/3);

在onLayout中可以获取到View中的子View进行高宽的动态变更

在onDraw中进行绘图:重点

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    this.setBackgroundColor(getResources().getColor(R.color.trade_tab));
    //添加X轴刻度和文字
    drawYklin(canvas);

    //添加X轴刻度和文字
    drawXklin(canvas);

    /*早盘价折线*/
    painm = new Paint();
    painm.setStyle(Paint.Style.FILL);
    painm.setAntiAlias(true); //去锯齿
    painm.setStrokeWidth(2);
    painm.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
    painm.setColor(context.getResources().getColor(R.color._DE9724));
    if(coordinatecoyp==null){
        coordinatecoyp = new ArrayList<>();
    }else {
        coordinatecoyp.clear();
    }
    int YMax = YLength - (YScalenum-1) * YScale;
    float KinMax = YLength - (YLength-YScale) * Tool.getSHJcalPrice(upPrice,downPrice,upPrice-downPrice);
    float C = KinMax - YMax;
    if(Mpricelist!=null){
        for(int i=0; i<Mpricelist.size(); i++){
            if(i!=Mpricelist.size()-1){
                float y = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Mpricelist.get(i).getYlin(),downPrice,upPrice-downPrice);
                float y1 = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Mpricelist.get(i+1).getYlin(),downPrice,upPrice-downPrice);
                canvas.drawLine( i * XScale + textWidth/2 + addXwidth,y- YScale/2- textheight/2,
                        (i+1) * XScale+ textWidth/2 + addXwidth,y1- YScale/2- textheight/2, painm);
            }
            for(SHjKinBean sHjKinBean: coordinate){
                if(sHjKinBean.getXlin().equals(Mpricelist.get(i).getXlin())&&sHjKinBean.getCoordinateX()==COORDINATEM){
                    SHjKinBean sHjKinBean1 = new SHjKinBean();
                    sHjKinBean1.setCoordinateY(YLength - (YLength-XScale) * Tool.getSHJcalPrice(Mpricelist.get(i).getYlin(),downPrice,upPrice-downPrice));
                    sHjKinBean1.setCoordinateX(  i * XScale+ textWidth/2 + addXwidth);
                    sHjKinBean1.setXlin(Mpricelist.get(i).getXlin());
                    coordinatecoyp.add(sHjKinBean1);
                }
            }
        }
    }
    /*午盘价折线*/
    paina = new Paint();
    paina.setStyle(Paint.Style.FILL);
    paina.setAntiAlias(true); //去锯齿
    paina.setStrokeWidth(2);
    paina.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
    paina.setColor(context.getResources().getColor(R.color._10A8F6));
    if(Apricelist!=null){
        for(int i=0; i<Apricelist.size(); i++){
            if(i!=Apricelist.size()-1){
                float y = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Apricelist.get(i).getYlin(),downPrice,upPrice-downPrice);
                float y1 = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Apricelist.get(i+1).getYlin(),downPrice,upPrice-downPrice);
                canvas.drawLine( i * XScale + textWidth/2 + addXwidth,y- YScale/2- textheight/2,
                        (i+1) * XScale + textWidth/2 + addXwidth,y1- YScale/2- textheight/2, paina);
            }
            for(SHjKinBean sHjKinBean: coordinate){
                if(sHjKinBean.getXlin().equals(Apricelist.get(i).getXlin())&&sHjKinBean.getCoordinateX()==COORDINATEA){
                    SHjKinBean sHjKinBean1 = new SHjKinBean();
                    sHjKinBean1.setCoordinateY(YLength - (YLength-XScale) * Tool.getSHJcalPrice(Apricelist.get(i).getYlin(),downPrice,upPrice-downPrice));
                    sHjKinBean1.setCoordinateX( i * XScale+ textWidth/2 + addXwidth);
                    sHjKinBean1.setXlin(Apricelist.get(i).getXlin());
                    coordinatecoyp.add(sHjKinBean1);
                }
            }
        }
    }
    //画点击弹出的详情
    if (needPop&&coordinatecoyp.size()>0){
        drawPopView(popX,popY,canvas);
    }
}

如果数据变更,我们提供一个供数据返回后页面调用的方法进行View的数据变化

public void PirceSetShjKinData(List<SHJBean> shjlist){
    this.shjlist = shjlist;
    UpteInvaldata();
    invalidate();
}

public void UpteInvaldata(){

    upPrice = 0;
    downPrice = 0;
    boolean isfrist= true;
    Mpricelist = new ArrayList<>();
    Apricelist = new ArrayList<>();
    coordinate = new ArrayList<>();//保存同一天价格高的xy轴坐标做
    String coordinatedata = "";
    for(SHJBean shjBeans:shjlist){
        try {
            float coordinatepriceM = -9999 , coordinatepriceA = -9999 ;
            float coordinateis = COORDINATEM;//默认早盘
                String price = shjBeans.getMprice()!=null?shjBeans.getMprice():shjBeans.getAprice();
                if(isfrist){//最低值需要拿第一个值
                    downPrice = Tool.getSHJDouble2(Double.valueOf(price));
                    isfrist = false;
                }
                coordinatedata = shjBeans.getData();
                Mpricelist.add(new SHjKinBean(Tool.getSHJDouble2(Double.valueOf(shjBeans.getMprice())),shjBeans.getData()));
                Apricelist.add(new SHjKinBean(Tool.getSHJDouble2(Double.valueOf(shjBeans.getAprice())),shjBeans.getData()));
                upPrice = upPrice>Tool.getSHJDouble2(Double.valueOf(price))?
                        upPrice:Tool.getSHJDouble2(Double.valueOf(price));//取出最高值
                downPrice = downPrice < Tool.getSHJDouble2(Double.valueOf(price))?
                        downPrice:Tool.getSHJDouble2(Double.valueOf(price));//取出最低值
                if(shjBeans.getMprice()!=null){
                    coordinatepriceM = Tool.getSHJDouble2(Double.valueOf(price));
                }else {
                    coordinatepriceA = Tool.getSHJDouble2(Double.valueOf(price));
                }

                /*拿出同一天最高价格是午盘还是早盘*/
            coordinateis = coordinatepriceM>coordinatepriceA?COORDINATEM:COORDINATEA;
            SHjKinBean KinBean = new SHjKinBean();
            KinBean.setCoordinateX(coordinateis);
            KinBean.setXlin(coordinatedata);
            coordinate.add(KinBean);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
    XLength  = srceenWidth-Tool.dpToPx(45);
    XScale = (XLength-(int) textWidth/2)/shjlist.size();
    if(shjlist.size()<5){
        addXwidth = XScale/2;
    }else {
        addXwidth = 0;
    }

    YLabel = new String[YScalenum];
    float Ypricepf = Tool.getSHJcalPrice(upPrice,downPrice,YScalenum-1);//均分-1
    for(int i=0;i<YScalenum;i++){
        float Ypriceft = Tool.getSHJDouble2(Ypricepf*i)+downPrice;
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        YLabel[i] = decimalFormat.format(Ypriceft);
    }
    XLabel = new String[shjlist.size()];
    for(int i=0;i<XLabel.length;i++){
        XLabel[i] = shjlist.get(i).getData();
    }
}

更新绘制需要调用invalidate();如果没有在UI线程里进行,则需要postInvalidate();

定义一个变量通知布局点击显示区域

public boolean onTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if(MOVENUM==0){
                downX = event.getX();
            }
            MOVENUM++;
            break;
        case MotionEvent.ACTION_MOVE:
            if(needPop){
                isMOVE = true;
                popX = event.getX();
                popY = event.getY();
                invalidate();
            }
            break;
        case MotionEvent.ACTION_UP:
            if(!needPop&&!isMOVE){
                needPop = !needPop;
            }else {
                float X = downX>event.getX()?downX-event.getX():event.getX()-downX;
                if(X<=Tool.dpToPx(15)&&MOVENUM>1){
                    MOVENUM=0;
                    needPop = !needPop;
                    isMOVE = false;
                }
            }
            popX = event.getX();
            popY = event.getY();
            invalidate();
            downX = event.getX();
            break;
    }
    return true;
}

同样,点击后需要通知View调用invalidate进行布局更新

点击后的手指区域处理代码:

 float coorx;//最小的点击差比
    int popWith = 0;
    private void drawPopView(float x,float y,Canvas canvas){
        int position=0;//最小的x轴
        popWith = Tool.dpToPx(15);
        for(int i=0;i<coordinatecoyp.size();i++){
            if(i==0){
                coorx = coordinatecoyp.get(i).getCoordinateX()>x?coordinatecoyp.get(i).getCoordinateX()-x:x-coordinatecoyp.get(i).getCoordinateX();
            }
            float coorxcopy = coordinatecoyp.get(i).getCoordinateX()>x?coordinatecoyp.get(i).getCoordinateX()-x:x-coordinatecoyp.get(i).getCoordinateX();
            if(coorx>coorxcopy){
                position = i;
                coorx = coorxcopy;
            }
        }
        x = coordinatecoyp.get(position).getCoordinateX();
        Paint paintzb = new Paint();//竖线
        paintzb.setStyle(Paint.Style.FILL);
        paintzb.setAntiAlias(true); //去锯齿
        paintzb.setStrokeWidth(1);
        paintzb.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        paintzb.setColor(context.getResources().getColor(R.color.text_usually));
        float newx;
        if(x>XLength){
            newx = XLength;
        }else {
            newx = x;
        }
        canvas.drawLine(newx, YLength - YScale/2- textheight/2, newx, YLength - Ypoplin * YScale- YScale/2- textheight/2, paintzb);
//        y = coordinatecoyp.get(position).getCoordinateY();
        Paint painapop = new Paint();
        painapop.setStyle(Paint.Style.STROKE);
        painapop.setAntiAlias(true); //去锯齿
        painapop.setStrokeWidth(2);
        painapop.setColor(context.getResources().getColor(R.color.text_usually));
        Path path= new Path();
        if(y-popWith*4 <10+ YPoint){
        /*超出上边框*/
            y  = (10+YPoint) - (y-popWith*4) +y;
        }else if(y>YLength-YScale/2- textheight/2){
        /*超出下边框*/
            float yend = y - YLength + textheight/2 + YScale/2;
            y  = y - yend;
        }
        String text = "交易日 :0101交易时间";
        float width = paint.measureText(text);//文本的宽度
        if(x+width>XLength){
        /*超出右边框*/
            path.moveTo(x-popWith,y-popWith*4);
            path.lineTo(x-popWith,y);
            path.lineTo(x-width,y);
            path.lineTo(x-width,y-popWith*4);
            path.lineTo(x-popWith,y-popWith*4);
        }else {
            path.moveTo(x+popWith,y-popWith*4);
            path.lineTo(x+popWith,y);
            path.lineTo(x+width,y);
            path.lineTo(x+width,y-popWith*4);
            path.lineTo(x+popWith,y-popWith*4);
        }
        canvas.drawPath(path, painapop);

        painapop.setStyle(Paint.Style.FILL);
        painapop.setColor(context.getResources().getColor(R.color.trade_tab));
        canvas.drawPath(path, painapop);
        String data="- -",pricem="- -",pricea="- -";
        for(int i=0;i<Mpricelist.size();i++){
            if(Mpricelist.get(i).getXlin().equals(coordinatecoyp.get(position).getXlin())){
                data = Mpricelist.get(i).getXlin();
                pricem = ""+Mpricelist.get(i).getYlin();
            }
        }
        for(int i=0;i<Apricelist.size();i++){
            if(Apricelist.get(i).getXlin().equals(coordinatecoyp.get(position).getXlin())){
                data = Apricelist.get(i).getXlin();
                pricea = ""+Apricelist.get(i).getYlin();
            }
        }
        int popHeight = (popWith*4)/8;
        if(x+width>XLength){
        /*超出右边框*/
            canvas.drawText("交易日:"+TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd",data),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*2+Tool.dpToPx(5),paint);
            canvas.drawText("早盘价:"+ Utils.pricesFormatFloat(pricem),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*4+Tool.dpToPx(5),painm);
            canvas.drawText("午盘价:"+Utils.pricesFormatFloat(pricea),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*6+Tool.dpToPx(5),paina);
        }else {
            canvas.drawText("交易日:"+TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd",data),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*2+Tool.dpToPx(5),paint);
            canvas.drawText("早盘价:"+Utils.pricesFormatFloat(pricem),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*4+Tool.dpToPx(5),painm);
            canvas.drawText("午盘价:"+Utils.pricesFormatFloat(pricea),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*6+Tool.dpToPx(5),paina);
        }
    }

整篇代码在下面贴出来

package com.sh.android.EGold.activity.price;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.sh.android.EGold.activity.R;
import com.sh.android.EGold.activity.main.SHJBean;
import com.sh.android.EGold.lib.kline.Tool;
import com.sh.android.EGold.util.TimeDateUtil;
import com.sh.android.EGold.util.Utils;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wzheng on 2017/8/30.
 */

public class ShjKinView extends View{
    private int srceenWidth;
    private int srceenHeight;
    private Context context;

    private int YPoint = 0;//上下边距26 上下边留白写定价值与日期
    private int XScale = 0; // X刻度长度
    private int YScale = 0; // Y刻度长度
    private int XLength = 0;//X的总长度
    private int YLength = 0;//Y的总长度
    private int YScalenum = 7;

    private String[] YLabel , XLabel;

    private List<SHJBean> shjlist;

    private List<SHjKinBean> Mpricelist ;
    private List<SHjKinBean> Apricelist ;
    private float downPrice,upPrice;

    private List<SHjKinBean> coordinate;
    private List<SHjKinBean> coordinatecoyp;
    //这样写的好处是coordinate的顺序不用控制,只需要对应xy轴里的coordinateX存储是否早>午判断存储y轴,用Xlin保存时间
    //因为早午盘x轴一样,先使用SHjKinBean
    private float COORDINATEM = -1 ,COORDINATEA = -2;

    private boolean needPop = false;
    private float popX,popY;//弹框
    private boolean isMOVE = false;
    private int MOVENUM = 0;
    private RecyclerView listView;

    private Paint painm , paina , paint;//红,蓝色,灰色

    private float textheight;
    private float textWidth;

    private float addXwidth = 0;
    private int Ypoplin = 0;

    public ShjKinView(Context context) {
        this(context, null);
    }

    public ShjKinView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context=context;
        init();
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        setMeasuredDimension(srceenWidth, Tool.getHeight(context)/3);
    }

    private void init(){

        srceenWidth = Tool.getWidth(context);
        srceenHeight = Tool.getHeight(context);
//        initTypeText();
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setAntiAlias(true); //去锯齿
        paint.setStrokeWidth(2);
        paint.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        paint.setColor(context.getResources().getColor(R.color._7C7F99));

        String text = "08-06";
        Rect rect = new Rect();
        paint.getTextBounds(text,0,text.length(), rect);
        textheight = rect.height();
        textWidth = rect.width();

        int srceenHeightpf = srceenHeight/100;
        YPoint = Tool.dpToPx(10);
        YLength = srceenHeightpf*PriceShjListKinView.Ypinf -YPoint;//K线高度缩小给上下留白
        YPoint = YPoint -(YPoint/2);//上下各一半
        YScale = YLength/YScalenum;//Y轴均分
    }


    public void PirceSetShjKinData(List<SHJBean> shjlist){
        this.shjlist = shjlist;
        UpteInvaldata();
        invalidate();
        postInvalidate();
    }

    public void UpteInvaldata(){

        upPrice = 0;
        downPrice = 0;
        boolean isfrist= true;
        Mpricelist = new ArrayList<>();
        Apricelist = new ArrayList<>();
        coordinate = new ArrayList<>();//保存同一天价格高的xy轴坐标做
        String coordinatedata = "";
        for(SHJBean shjBeans:shjlist){
            try {
                float coordinatepriceM = -9999 , coordinatepriceA = -9999 ;
                float coordinateis = COORDINATEM;//默认早盘
                    String price = shjBeans.getMprice()!=null?shjBeans.getMprice():shjBeans.getAprice();
                    if(isfrist){//最低值需要拿第一个值
                        downPrice = Tool.getSHJDouble2(Double.valueOf(price));
                        isfrist = false;
                    }
                    coordinatedata = shjBeans.getData();
                    Mpricelist.add(new SHjKinBean(Tool.getSHJDouble2(Double.valueOf(shjBeans.getMprice())),shjBeans.getData()));
                    Apricelist.add(new SHjKinBean(Tool.getSHJDouble2(Double.valueOf(shjBeans.getAprice())),shjBeans.getData()));
                    upPrice = upPrice>Tool.getSHJDouble2(Double.valueOf(price))?
                            upPrice:Tool.getSHJDouble2(Double.valueOf(price));//取出最高值
                    downPrice = downPrice < Tool.getSHJDouble2(Double.valueOf(price))?
                            downPrice:Tool.getSHJDouble2(Double.valueOf(price));//取出最低值
                    if(shjBeans.getMprice()!=null){
                        coordinatepriceM = Tool.getSHJDouble2(Double.valueOf(price));
                    }else {
                        coordinatepriceA = Tool.getSHJDouble2(Double.valueOf(price));
                    }

                    /*拿出同一天最高价格是午盘还是早盘*/
                coordinateis = coordinatepriceM>coordinatepriceA?COORDINATEM:COORDINATEA;
                SHjKinBean KinBean = new SHjKinBean();
                KinBean.setCoordinateX(coordinateis);
                KinBean.setXlin(coordinatedata);
                coordinate.add(KinBean);
            }catch (Exception e){
                e.printStackTrace();
            }

        }
        XLength  = srceenWidth-Tool.dpToPx(45);
        XScale = (XLength-(int) textWidth/2)/shjlist.size();
        if(shjlist.size()<5){
            addXwidth = XScale/2;
        }else {
            addXwidth = 0;
        }

        YLabel = new String[YScalenum];
        float Ypricepf = Tool.getSHJcalPrice(upPrice,downPrice,YScalenum-1);//均分-1
        for(int i=0;i<YScalenum;i++){
            float Ypriceft = Tool.getSHJDouble2(Ypricepf*i)+downPrice;
            DecimalFormat decimalFormat = new DecimalFormat("0.00");
            YLabel[i] = decimalFormat.format(Ypriceft);
        }
        XLabel = new String[shjlist.size()];
        for(int i=0;i<XLabel.length;i++){
            XLabel[i] = shjlist.get(i).getData();
        }
    }
    float downX = 0;

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                listView.requestDisallowInterceptTouchEvent(true);
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                listView.requestDisallowInterceptTouchEvent(false);
                break;
        }
        return super.dispatchTouchEvent(event);
    }

    @Override
    protected void onAnimationStart() {
        super.onAnimationStart();
    }

    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                if(MOVENUM==0){
                    downX = event.getX();
                }
                MOVENUM++;
                break;
            case MotionEvent.ACTION_MOVE:
                if(needPop){
                    isMOVE = true;
                    popX = event.getX();
                    popY = event.getY();
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if(!needPop&&!isMOVE){
                    needPop = !needPop;
                }else {
                    float X = downX>event.getX()?downX-event.getX():event.getX()-downX;
                    if(X<=Tool.dpToPx(15)&&MOVENUM>1){
                        MOVENUM=0;
                        needPop = !needPop;
                        isMOVE = false;
                    }
                }
                popX = event.getX();
                popY = event.getY();
                invalidate();
                downX = event.getX();
                break;
        }
        return true;
    }
    public void setlistview(RecyclerView listview){
        listView = listview;
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        this.setBackgroundColor(getResources().getColor(R.color.trade_tab));
        //添加X轴刻度和文字
        drawYklin(canvas);

        //添加X轴刻度和文字
        drawXklin(canvas);

        /*早盘价折线*/
        painm = new Paint();
        painm.setStyle(Paint.Style.FILL);
        painm.setAntiAlias(true); //去锯齿
        painm.setStrokeWidth(2);
        painm.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        painm.setColor(context.getResources().getColor(R.color._DE9724));
        if(coordinatecoyp==null){
            coordinatecoyp = new ArrayList<>();
        }else {
            coordinatecoyp.clear();
        }
        int YMax = YLength - (YScalenum-1) * YScale;
        float KinMax = YLength - (YLength-YScale) * Tool.getSHJcalPrice(upPrice,downPrice,upPrice-downPrice);
        float C = KinMax - YMax;
        if(Mpricelist!=null){
            for(int i=0; i<Mpricelist.size(); i++){
                if(i!=Mpricelist.size()-1){
                    float y = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Mpricelist.get(i).getYlin(),downPrice,upPrice-downPrice);
                    float y1 = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Mpricelist.get(i+1).getYlin(),downPrice,upPrice-downPrice);
                    canvas.drawLine( i * XScale + textWidth/2 + addXwidth,y- YScale/2- textheight/2,
                            (i+1) * XScale+ textWidth/2 + addXwidth,y1- YScale/2- textheight/2, painm);
                }
                for(SHjKinBean sHjKinBean: coordinate){
                    if(sHjKinBean.getXlin().equals(Mpricelist.get(i).getXlin())&&sHjKinBean.getCoordinateX()==COORDINATEM){
                        SHjKinBean sHjKinBean1 = new SHjKinBean();
                        sHjKinBean1.setCoordinateY(YLength - (YLength-XScale) * Tool.getSHJcalPrice(Mpricelist.get(i).getYlin(),downPrice,upPrice-downPrice));
                        sHjKinBean1.setCoordinateX(  i * XScale+ textWidth/2 + addXwidth);
                        sHjKinBean1.setXlin(Mpricelist.get(i).getXlin());
                        coordinatecoyp.add(sHjKinBean1);
                    }
                }
            }
        }
        /*午盘价折线*/
        paina = new Paint();
        paina.setStyle(Paint.Style.FILL);
        paina.setAntiAlias(true); //去锯齿
        paina.setStrokeWidth(2);
        paina.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        paina.setColor(context.getResources().getColor(R.color._10A8F6));
        if(Apricelist!=null){
            for(int i=0; i<Apricelist.size(); i++){
                if(i!=Apricelist.size()-1){
                    float y = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Apricelist.get(i).getYlin(),downPrice,upPrice-downPrice);
                    float y1 = YLength - (YLength-YScale+C) * Tool.getSHJcalPrice(Apricelist.get(i+1).getYlin(),downPrice,upPrice-downPrice);
                    canvas.drawLine( i * XScale + textWidth/2 + addXwidth,y- YScale/2- textheight/2,
                            (i+1) * XScale + textWidth/2 + addXwidth,y1- YScale/2- textheight/2, paina);
                }
                for(SHjKinBean sHjKinBean: coordinate){
                    if(sHjKinBean.getXlin().equals(Apricelist.get(i).getXlin())&&sHjKinBean.getCoordinateX()==COORDINATEA){
                        SHjKinBean sHjKinBean1 = new SHjKinBean();
                        sHjKinBean1.setCoordinateY(YLength - (YLength-XScale) * Tool.getSHJcalPrice(Apricelist.get(i).getYlin(),downPrice,upPrice-downPrice));
                        sHjKinBean1.setCoordinateX( i * XScale+ textWidth/2 + addXwidth);
                        sHjKinBean1.setXlin(Apricelist.get(i).getXlin());
                        coordinatecoyp.add(sHjKinBean1);
                    }
                }
            }
        }
        //画点击弹出的详情
        if (needPop&&coordinatecoyp.size()>0){
            drawPopView(popX,popY,canvas);
        }
    }

    float coorx;//最小的点击差比
    int popWith = 0;
    private void drawPopView(float x,float y,Canvas canvas){
        int position=0;//最小的x轴
        popWith = Tool.dpToPx(15);
        for(int i=0;i<coordinatecoyp.size();i++){
            if(i==0){
                coorx = coordinatecoyp.get(i).getCoordinateX()>x?coordinatecoyp.get(i).getCoordinateX()-x:x-coordinatecoyp.get(i).getCoordinateX();
            }
            float coorxcopy = coordinatecoyp.get(i).getCoordinateX()>x?coordinatecoyp.get(i).getCoordinateX()-x:x-coordinatecoyp.get(i).getCoordinateX();
            if(coorx>coorxcopy){
                position = i;
                coorx = coorxcopy;
            }
        }
        x = coordinatecoyp.get(position).getCoordinateX();
        Paint paintzb = new Paint();//竖线
        paintzb.setStyle(Paint.Style.FILL);
        paintzb.setAntiAlias(true); //去锯齿
        paintzb.setStrokeWidth(1);
        paintzb.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.font_super_smallest));
        paintzb.setColor(context.getResources().getColor(R.color.text_usually));
        float newx;
        if(x>XLength){
            newx = XLength;
        }else {
            newx = x;
        }
        canvas.drawLine(newx, YLength - YScale/2- textheight/2, newx, YLength - Ypoplin * YScale- YScale/2- textheight/2, paintzb);
//        y = coordinatecoyp.get(position).getCoordinateY();
        Paint painapop = new Paint();
        painapop.setStyle(Paint.Style.STROKE);
        painapop.setAntiAlias(true); //去锯齿
        painapop.setStrokeWidth(2);
        painapop.setColor(context.getResources().getColor(R.color.text_usually));
        Path path= new Path();
        if(y-popWith*4 <10+ YPoint){
        /*超出上边框*/
            y  = (10+YPoint) - (y-popWith*4) +y;
        }else if(y>YLength-YScale/2- textheight/2){
        /*超出下边框*/
            float yend = y - YLength + textheight/2 + YScale/2;
            y  = y - yend;
        }
        String text = "交易日 :0101交易时间";
        float width = paint.measureText(text);//文本的宽度
        if(x+width>XLength){
        /*超出右边框*/
            path.moveTo(x-popWith,y-popWith*4);
            path.lineTo(x-popWith,y);
            path.lineTo(x-width,y);
            path.lineTo(x-width,y-popWith*4);
            path.lineTo(x-popWith,y-popWith*4);
        }else {
            path.moveTo(x+popWith,y-popWith*4);
            path.lineTo(x+popWith,y);
            path.lineTo(x+width,y);
            path.lineTo(x+width,y-popWith*4);
            path.lineTo(x+popWith,y-popWith*4);
        }
        canvas.drawPath(path, painapop);

        painapop.setStyle(Paint.Style.FILL);
        painapop.setColor(context.getResources().getColor(R.color.trade_tab));
        canvas.drawPath(path, painapop);
        String data="- -",pricem="- -",pricea="- -";
        for(int i=0;i<Mpricelist.size();i++){
            if(Mpricelist.get(i).getXlin().equals(coordinatecoyp.get(position).getXlin())){
                data = Mpricelist.get(i).getXlin();
                pricem = ""+Mpricelist.get(i).getYlin();
            }
        }
        for(int i=0;i<Apricelist.size();i++){
            if(Apricelist.get(i).getXlin().equals(coordinatecoyp.get(position).getXlin())){
                data = Apricelist.get(i).getXlin();
                pricea = ""+Apricelist.get(i).getYlin();
            }
        }
        int popHeight = (popWith*4)/8;
        if(x+width>XLength){
        /*超出右边框*/
            canvas.drawText("交易日:"+TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd",data),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*2+Tool.dpToPx(5),paint);
            canvas.drawText("早盘价:"+ Utils.pricesFormatFloat(pricem),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*4+Tool.dpToPx(5),painm);
            canvas.drawText("午盘价:"+Utils.pricesFormatFloat(pricea),x-width+Tool.dpToPx(10),y-popWith*4+popHeight*6+Tool.dpToPx(5),paina);
        }else {
            canvas.drawText("交易日:"+TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd",data),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*2+Tool.dpToPx(5),paint);
            canvas.drawText("早盘价:"+Utils.pricesFormatFloat(pricem),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*4+Tool.dpToPx(5),painm);
            canvas.drawText("午盘价:"+Utils.pricesFormatFloat(pricea),x+popWith+Tool.dpToPx(10),y-popWith*4+popHeight*6+Tool.dpToPx(5),paina);
        }
    }

    /**
     * X轴刻度 Y轴边线
     * */
    private void drawYklin(Canvas canvas){
        if(XLabel==null){
            return;
        }
        int left,right,centen;
        if(XLabel.length%2==0){
            centen =  XLabel.length/2;
        }
        else{
            centen =  (XLabel.length-1)/2;
        }
        if(centen%2==0){
            left = centen /2;
            right =centen+centen /2;
        }else {
            left = (centen-1) /2;
            right = centen+(centen-1)/2;
        }
        for(int i=0;i < XLabel.length;i++){
            if(i==0||i==centen||i==left||i==right){
                canvas.drawText(TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd", XLabel[i]),  i * XScale + addXwidth, YLength +Tool.dpToPx(10)- YScale/2, paint);//文字
            }else {
                Rect rect = new Rect();
                paint.getTextBounds(TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd", XLabel[i]), 0, TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd", XLabel[i]).length(), rect);
                if(i==XLabel.length-1){
                    canvas.drawText(TimeDateUtil.changeDateFormat("yyyyMMdd", "MM-dd", XLabel[i]), i * XScale + addXwidth, YLength +Tool.dpToPx(10)- YScale/2, paint);//文字
                }
            }
        }
    }
    /**
     * Y轴刻度  X轴边线
     * */
    private void drawXklin(Canvas canvas){
        if(YLabel==null){
            return;
        }
        paint.setStrokeWidth(1);
        paint.setColor(context.getResources().getColor(R.color._7C7F99));
        for(int i=0; i * YScale < YLength; i++) {
            if(i >= YLength/YScale){
                continue;
            }
            Ypoplin = i;
            canvas.drawLine(0, YLength - i * YScale - YScale/2 - textheight/2, XLength, YLength - i * YScale- YScale/2- textheight/2, paint);  //刻度
        }
        paint.setStrokeWidth(2);
    }

    class SHjKinBean{

        public String Xlin;
        public float Ylin;
        public float coordinateX;
        public float coordinateY;

        SHjKinBean(){

        }

        SHjKinBean(float ylin,String xlin){
            Ylin = ylin;
            Xlin = xlin;
        }

        public float getCoordinateX() {
            return coordinateX;
        }

        public void setCoordinateX(float coordinateX) {
            this.coordinateX = coordinateX;
        }

        public float getCoordinateY() {
            return coordinateY;
        }

        public void setCoordinateY(float coordinateY) {
            this.coordinateY = coordinateY;
        }

        public String getXlin() {
            return Xlin;
        }

        public void setXlin(String xlin) {
            Xlin = xlin;
        }

        public float getYlin() {
            return Ylin;
        }

        public void setYlin(float ylin) {
            Ylin = ylin;
        }
    }

    /*详细信息屏蔽*/
    public void gonePop(){
        if(needPop){
            needPop = !needPop;
            MOVENUM=0;
            isMOVE = false;
            invalidate();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值