股票行情图:一个fragment画K线主副图

相关阅读:

  • 股票行情图:需求概述
  • 股票行情图:MPAndroidChart文章(我曾经的参考)
  • 股票行情图:一个fragment画K线主副图
  • 股票行情图:数据工厂类和数据源
  • 股票行情图:使用到的常量类和工具类
  • 股票行情图:Udp更新数据(MPAndroidChart更新视图)
  • 股票行情图:主副图图形数据设置(MPAndroidChart图形设置)
  • 股票行情图:MACD指标算法及其MPAndroidChart图形设置
  • 股票行情图:RSI指标算法及其MPAndroidChart图形设置
  • 股票行情图:BOLL指标算法及其MPAndroidChart图形设置
  • 股票行情图:KDJ指标算法及其MPAndroidChart图形设置
  • 股票行情图:CCI指标算法及其MPAndroidChart图形设置
  • 股票行情图:PSY指标算法及其MPAndroidChart图形设置
  • 股票行情图:WR指标算法及其MPAndroidChart图形设置
  • 股票行情图:DMI指标算法及其MPAndroidChart图形设置
  • 股票行情图:ROC指标算法及其MPAndroidChart图形设置
  • 股票行情图:TRIS指标算法及其MPAndroidChart图形设置
    【原创作品,版权所有wblobin[汇通财经],转载请标注来源,否则视为盗版侵权。】

国际管理贴一张效果

一、真实K线图片(汇通财经V311,即将上线)

【ps:图中汇通财经字样和Logo是水印】


股票行情图:一个fragment画K线主副图_第1张图片
K线主副图带高亮.png

二、K线图Demo版

【ps:图中汇通财经字样和Logo是水印】


股票行情图:一个fragment画K线主副图_第2张图片
K线Demo.png

三、源码

1、布局:a0000kline_f.xml




    

        

            
            
            

                

                

                

                

                

                
            
        

        

            
            

            

                
                
                
                
                
            
        
    

    

        

        
    


2、KLineF.java

最后贴出变量;废话不多说看代码,都有备注

2.1、(下面是onCreateView())

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.a0000kline_f, container, false);
        view.setBackgroundColor(BG_COLOR);
        unBinder = ButterKnife.bind(this, view);//butterknife 8 之后的配置
        //ButterKnife.bind(this,view); //butterknife 8 之前的配置
        chartMarginRight = Utils.dip2px(getActivity(),60);//图表右边的距离
        chartMarginBottom = Utils.dip2px(getActivity(),20);//图表底部的距离
        initChart();
        doNetWork();//原本是网络请求,这里是本地数据,懒得改名字
        return view;
    }

2.2、下面是onCreateView()中提到的initChart()

    private void initChart() {
        /*主图和副图 联动 绑定*/
        klineChartDeputy.setOnChartGestureListener(new MyOnChartGestureListener(klineChartDeputy, klineChartMaster));// 副图滑动 带动副图控件滑动(即:将副图控的滑动事件 传递给 主图控件)
        klineChartMaster.setOnChartGestureListener(new MyOnChartGestureListener(klineChartMaster, klineChartDeputy));// 将主图控的滑动事件 传递给 副图控件

        initChartMaster(); //初始化主图
        initChartDeputy(); //初始化副图

        klineChartDeputy.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
            @Override
            public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
                isHighLightTime = true;
                klineChartMaster.highlightValues(new Highlight[]{h});//副图十字光标高亮选中 设置主图也高亮
                setParameterDataSelected(h.getXIndex());//十字光标高亮选中 主副图的参数的显示设置
            }
            @Override
            public void onNothingSelected() {
                klineChartMaster.highlightValues(null);//主图 取消十字光标高亮选中
                klineChartDeputy.highlightValues(null);//副图 取消十字光标高亮选中
            }
        });
        klineChartMaster.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
            @Override
            public void onValueSelected(Entry e, int dataSetIndex, Highlight h) {
                isHighLightTime = true;
                klineChartDeputy.highlightValues(new Highlight[]{h});//主图十字光标高亮选中 设置副图也高亮
                setParameterDataSelected(h.getXIndex());//十字光标高亮选中 主副图的参数的显示设置
            }
            @Override
            public void onNothingSelected() {
                klineChartMaster.highlightValues(null);
                klineChartDeputy.highlightValues(null);
            }
        });
    }

    //初始化主图
    private void initChartMaster() {
        klineChartMaster.setDrawBorders(true);//设置图表内格子外的边框是否显示
        klineChartMaster.setBorderWidth(0.8f);//上面边框的宽度,float类型,dp单位
        klineChartMaster.setBorderColor(COLOR_LINE_DEFAULT);//上面的边框颜色
        klineChartMaster.setDescription("");//"K线" 不显示 设为"" 空字符串
        klineChartMaster.setDragEnabled(true);// 是否可以拖拽 //setTouchEnabled(true); 设置是否可以触摸
        klineChartMaster.setScaleYEnabled(false);//是否可以缩放 仅y轴
        klineChartMaster.setNoDataText("数据加载中");
        klineChartMaster.setNoDataTextColor(COLOR_TEXT_DEFAULT);
        //klineChartMaster.setVisibleXRangeMinimum(20);  //一个界面最少显示多少个点,放大后最多 放大到 剩多少 个点

        Legend combinedchartLegend = klineChartMaster.getLegend();// 设置比例图表示,就是那个一组y的value的
        combinedchartLegend.setEnabled(false);

        axisX_Master = klineChartMaster.getXAxis();//获取图表的 X轴 管理事件
        axisX_Master.setDrawLabels(true); //是否显示 坐标轴上的刻度,默认是true
        axisX_Master.setDrawGridLines(true);//是否显示 坐标轴上的刻度竖线,默认是true
        axisX_Master.enableGridDashedLine(DASHED_LENGTH_LINE, DASHED_LENGTH_SPACE, 0.0f);//虚线表示X轴上的刻度竖线(float lineLength, float spaceLength, float phase)三个参数,1.线长,2.虚线间距,3.虚线开始坐标
        axisX_Master.setDrawAxisLine(false);//是否绘制坐标轴的线,即含有坐标的那条线,默认是true
        axisX_Master.setTextColor(COLOR_TEXT_DEFAULT);// 轴上的刻度的颜色
        axisX_Master.setPosition(XAxis.XAxisPosition.BOTTOM);//把坐标轴放在上下 参数有:TOP, BOTTOM, BOTH_SIDED, TOP_INSIDE or BOTTOM_INSIDE.
        axisX_Master.setGridColor(COLOR_LINE_DEFAULT);// 轴上的刻度竖线的颜色

        axisLeftMaster = klineChartMaster.getAxisLeft();//获取图表的 Y轴左边 管理事件
        axisLeftMaster.setDrawLabels(false);
        axisLeftMaster.setDrawGridLines(false);
        axisLeftMaster.setDrawAxisLine(false);

        axisRightMaster = klineChartMaster.getAxisRight();//获取图表的 Y轴右边 管理事件
        axisRightMaster.setDrawLabels(true);
        axisRightMaster.setLabelCount(5, true);//第一个参数是 轴坐标的个数,第二个参数是 是否不均匀分布,true是不均匀分布
        axisRightMaster.setDrawGridLines(true);
        axisRightMaster.enableGridDashedLine(DASHED_LENGTH_LINE, DASHED_LENGTH_SPACE, 0.0f);
        axisRightMaster.setDrawAxisLine(false);
        axisRightMaster.setTextColor(COLOR_TEXT_DEFAULT);
        axisRightMaster.setGridColor(COLOR_LINE_DEFAULT);
        axisRightMaster.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//参数是INSIDE_CHART(Y轴坐标在内部) 或 OUTSIDE_CHART(在外部(默认是这个))
        axisRightMaster.setValueFormatter(new VolFormatter(dfs[positionDF]));//dfs[positionDF]

        klineChartMaster.setAutoScaleMinMaxEnabled(true);//自动缩放
        klineChartMaster.setDragDecelerationEnabled(true);//如果设置为真,图表继续滚动后,触摸了。默认值:真。
        klineChartMaster.setDragDecelerationFrictionCoef(DECELERATION_FRICTION_COEFFICIENT);////设置 减速摩擦系数

    }

    //初始化副图
    private void initChartDeputy() {
        klineChartDeputy.setDrawBorders(true);
        klineChartDeputy.setBorderWidth(0.8f);
        klineChartDeputy.setBorderColor(COLOR_LINE_DEFAULT);
        klineChartDeputy.setDescription("");//"指标" 不显示 设为"" 空字符串
        klineChartDeputy.setDragEnabled(true);
        klineChartDeputy.setScaleYEnabled(false);
        klineChartDeputy.setNoDataText("");
        //klineChartDeputy.setVisibleXRangeMinimum(20);  //一个界面最少显示多少个点,放大后最多 放大到 剩多少 个点

        Legend barChartLegend = klineChartDeputy.getLegend();
        barChartLegend.setEnabled(false);

        axisX_Deputy = klineChartDeputy.getXAxis(); //bar x y轴
        axisX_Deputy.setDrawLabels(false);
        axisX_Deputy.setDrawGridLines(true);
        axisX_Deputy.enableGridDashedLine(DASHED_LENGTH_LINE, DASHED_LENGTH_SPACE, 0.0f);
        axisX_Deputy.setDrawAxisLine(false);
        axisX_Deputy.setPosition(XAxis.XAxisPosition.BOTTOM);
        axisX_Deputy.setGridColor(COLOR_LINE_DEFAULT);//kline_chart_line

        axisLeftDeputy = klineChartDeputy.getAxisLeft();
        axisLeftDeputy.setDrawLabels(false);
        axisLeftDeputy.setDrawGridLines(false);
        axisLeftDeputy.setDrawAxisLine(false);
        //axisLeftDeputy.setShowOnlyMinMax(true);

        axisRightDeputy = klineChartDeputy.getAxisRight();
        axisRightDeputy.setDrawLabels(true);
        axisRightDeputy.setLabelCount(3, true);
        axisRightDeputy.setDrawGridLines(true);
        axisRightDeputy.enableGridDashedLine(DASHED_LENGTH_LINE, DASHED_LENGTH_SPACE, 0.0f);
        axisRightDeputy.setDrawAxisLine(false);
        axisRightDeputy.setTextColor(COLOR_TEXT_DEFAULT);
        axisRightDeputy.setGridColor(COLOR_LINE_DEFAULT);
        axisRightDeputy.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        axisRightDeputy.setValueFormatter(new VolFormatter(dfs[positionDF]));//dfs[positionDF]

        klineChartDeputy.setAutoScaleMinMaxEnabled(true);//自动缩放
        klineChartDeputy.setDragDecelerationEnabled(true);
        klineChartDeputy.setDragDecelerationFrictionCoef(DECELERATION_FRICTION_COEFFICIENT);//设置 减速摩擦系数
    }

2.3、初始化差不多结束了 下面是onCreateView()中提到的doNetWork()获取数据

    private void doNetWork() {
        isHighLightTime = false;
        progressBarRL.setVisibility(View.VISIBLE);
        //mData = new DataParse();
        if (typeTime < 6) {//5、15、30、60、2、4、//"k线-日、周、月十字光标去掉时分秒,5、15、30、60、2h、4h去掉秒,如线上版本"
            formatDate = "yyyy-MM-dd HH:mm";
        } else {// month
            formatDate = "yyyy-MM-dd";
        }
        kLineDatas = null;
        kLineDatas = new ArrayList();
        String data="";
        switch (typeIndex) {
            case 0:
                data = new Min5().getData();
                break;
            case 1:
                data = new Min15().getData();
                break;
            case 2:
                data = new Min30().getData();
                break;
            case 3:
                data = new Min60().getData();
                break;
            case 4:
                data = new Hour2().getData();
                break;
            case 5:
                data = new Hour4().getData();
                break;
            case 6:
                data = new Day().getData();
                break;
            case 7:
                data = new Week().getData();
                break;
            case 8:
                data = new Month().getData();
                break;
        }
        kLineDatas = Utils.getJson2KLine(data);
        onSuccess();
    }
    public void onSuccess( ) {//原本这个是网络请求 成功返回数据的,这里是固定数据 就去掉监听事件
        if(kLineDatas==null || kLineDatas.size()==0){
            setNoData();
            return;
        }
        data2show_master.setVisibility(View.VISIBLE);
        data2show_deputy.setVisibility(View.VISIBLE);
        setData();
        progressBarRL.setVisibility(View.GONE);
    }
    private void setNoData(){
        klineChartMaster.setNoDataText("暂无数据");
        data2show_master.setVisibility(View.GONE);
        data2show_deputy.setVisibility(View.GONE);
        progressBarRL.setVisibility(View.GONE);
    }

2.4、获取数据后把数据设置到Chart中

    //初始化 网络过来的数据
    private void setData() {
        xVals = new ArrayList<>();//X轴坐标点的集合 即日期
        candleEntries = new ArrayList<>();
        line5Entries = new ArrayList<>();
        line10Entries = new ArrayList<>();
        line20Entries = new ArrayList<>();
        for (int i = 0; i < kLineDatas.size(); i++) {
            KLineBean kLineBean = kLineDatas.get(i);
            String date = TimeUtils.time2Date(kLineBean.date, formatDate);//
            float open = kLineBean.open;
            float close = kLineBean.close;
            float high = kLineBean.high;
            float low = kLineBean.low;
            float vol = kLineBean.vol;
            xVals.add(date + "");
            candleEntries.add(new CandleEntry(i, high, low, open, close));
            line5Entries.add(new Entry(getSum(CMA5, i), i));//Object data  此条目表示的附加数据的数据点。此条目表示的附加数据的位置。
            line10Entries.add(new Entry(getSum(CMA10, i), i));
            line20Entries.add(new Entry(getSum(CMA20, i), i));
        }
        if (!isSetxScaleCombin) {
            setxScaleCombin();
        }
        setDataMaster();
        setDataDeputy();
    }
    private float getSum(int typeCMA, int position) {//计算平均值
        if (position < typeCMA - 1) {
            return kLineDatas.get(position).close;
        } else {
            float sum = 0;
            for (int i = position + 1 - typeCMA; i <= position; i++) {
                sum += kLineDatas.get(i).close;
            }
            return formatDataDF(sum / typeCMA);
        }
    }
    public static float formatDataDF(float fomate) {//工具,用于格式化float 保留几位小数点
        float result = 0.0f;
        try {
            result = Float.valueOf(dfs[positionDF].format(fomate));
        } catch (Exception e) {
        }
        return result;
    }


    private boolean isSetxScaleCombin = false;
    private void setxScaleCombin() {
        visibleXIndexLeft = 0;
        visibleXIndexRight = 0;
        final ViewPortHandler viewPortHandlerBar = klineChartDeputy.getViewPortHandler();
        viewPortHandlerBar.setMaximumScaleX(culcMaxscale(xVals.size()));
        Matrix touchmatrix = viewPortHandlerBar.getMatrixTouch();
        touchmatrix.postScale(MATRIX_SCALE_X, MATRIX_SCALE_Y);
        final ViewPortHandler viewPortHandlerCombin = klineChartMaster.getViewPortHandler();
        viewPortHandlerCombin.setMaximumScaleX(culcMaxscale(xVals.size()));
        Matrix matrixCombin = viewPortHandlerCombin.getMatrixTouch();
        matrixCombin.postScale(MATRIX_SCALE_X, MATRIX_SCALE_Y);
    }
    private float culcMaxscale(float count) {
        float max = 1;
        max = count / 127 * 5;
        return max;
    }

    private void setDataMaster() {  //设置 主图数据 并展示
        CandleData candleData = new CandleData(xVals, CombinedDataSet.setCandleData(candleEntries, true));
        ArrayList sets = new ArrayList<>();//坐标线的集合。  //坐标线,LineDataSet(坐标点的集合, 线的描述或名称);
        sets.add(CombinedDataSet.setLine(1, line5Entries,true, true));//CMA5 //高亮
        sets.add(CombinedDataSet.setLine(2, line10Entries, false, false));//CMA10
        sets.add(CombinedDataSet.setLine(3, line20Entries, false, false));//CMA20
        CombinedData combinedData = new CombinedData(xVals);
        LineData lineData = new LineData(xVals, sets);//LineData(X坐标轴的集合, 坐标线的集合);
        combinedData.setData(candleData);
        combinedData.setData(lineData);
        klineChartMaster.setData(combinedData);

        //MyApplication.htlog.e(",isSetxScaleCombin:"+isSetxScaleCombin + ",visibleXIndexRight:"+visibleXIndexRight + ",visibleXIndexLeft:"+visibleXIndexLeft + ",kLineDatas.size():"+kLineDatas.size() + ",getXChartMax="+klineChartMaster.getXChartMax() );

        klineChartMaster.setViewPortOffsets(5, 12, chartMarginRight, chartMarginBottom);    // left top right bottom    //这个要放在这里  不然会出现 上下滑动的问题
        klineChartDeputy.setViewPortOffsets(5, 12, chartMarginRight, 10);   // left top right bottom           //必须放在 moveViewToX 前面不然会出现偏移
        setParameterData(kLineDatas.size() - 1);//  把 视图上最右边(最大)的值的位置 设置到MA5/MA10/MA20
        klineChartMaster.moveViewToX(kLineDatas.size() - 1f);//kLineDatas.size() - 1//klineChartMaster.getXChartMax()-1
    }
    private void setDataDeputy() {  //设置 副图数据 并展示
        if(typeIndex==0) {
            LimitLine ll = new LimitLine(0.00f, "");//可以设置一条警戒线,
            ll.setLineColor(Color.parseColor("#f847bd"));//COLOR_INDEX_LINE3:#f847bd    static final int COLOR_CANDLE_UP = 0xffe32222;//Color.parseColor("#FFe32222");//
            ll.setLineWidth(0.4f);
            //ll.enableDashedLine(DASHED_LENGTH_LINE, DASHED_LENGTH_SPACE, 0.0f);//虚线
            axisRightDeputy.addLimitLine(ll);
        }else {
            axisRightDeputy.removeAllLimitLines();
        }
        klineChartDeputy.setData(getCombinedData4Index());
        setParameterData();

        if(!isSetxScaleCombin){// || visibleXIndexRight==0 || visibleXIndexRight==visibleXIndexLeft){//
            klineChartDeputy.moveViewToX(kLineDatas.size() - 1f);//kLineDatas.size() - 1//klineChartDeputy.getXChartMax()-1
            //isSetxScaleCombin = true;
            notifyChartMaster();//延迟36毫米,再次更新Chart;防止 右边数值 显示不全的问题 //其实moveViewToX 有更新图标的功能
        }else {
            if( visibleXIndexRight==0 || visibleXIndexRight==visibleXIndexLeft){
                klineChartDeputy.moveViewToX(kLineDatas.size() - 1f);
            }else {
                klineChartDeputy.moveViewToX(visibleXIndexLeft);//visibleXIndexLeft
            }
        }
    }

    private void notifyChartMaster() {  // 更新视图 设置,更新chart的显示效果
        isSetxScaleCombin = true;
        handler.sendEmptyMessageDelayed(CHART_NOTIFY_DATA, 36);
    }
    private void notifyChartDeputy() {  // 更新视图 设置,更新chart的显示效果
        handler.sendEmptyMessageDelayed(CHART_NOTIFY_DATA_AGAIN, 300);
    }

2.5、下面是设置副图的数据 klineChartDeputy.setData(getCombinedData4Index());

    /**
     * 以下都是指标的算法 以及 得出的数据
     */
    private float macdData[][];//private final int macdParam[] = {12, 26, 9};
    private float rsiData[][];//private final int rsiParam[] = {6, 12, 24};
    private float bollData[][];//private final int bollParam[] = {26, 2};
    private float kdjData[][];//private final int kdjParam[] = {9, 3, 3};
    private float cciData[][];//private final int cciParam[] = {14};
    private float psyData[][];//private final int psyParam[] = {12, 24};
    private float wrData[][];//private final int wrParam[] = {10, 6};
    private float dmiData[][];//private final int dmiParam[] = {14, 6};
    private float sarData[][];//private final int dmiParam[] = {14, 6};
    private float rocData[][];//private final int dmiParam[] = {14, 6};
    private float trisData[][];//private final int dmiParam[] = {14, 6};

    private CombinedData getCombinedData4Index() {
        CombinedData combinedData = null;
        if (kLineDatas == null || kLineDatas.size() == 0) {
            return combinedData;
        }
        switch (typeIndex) {
            case 0:
                macdData = CalculateIndexListData.macdDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setMacdData(kLineDatas, macdData, xVals);
                break;
            case 1:
                rsiData = CalculateIndexListData.rsiDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setRsiData(kLineDatas, rsiData, xVals);
                break;
            case 2:
                bollData = CalculateIndexListData.bollDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setBollData(kLineDatas, bollData, xVals,candleEntries);
                break;
            case 3:
                kdjData = CalculateIndexListData.kdjDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setKdjData(kLineDatas, kdjData, xVals);
                break;
            case 4:
                cciData = CalculateIndexListData.cciDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setCciData(kLineDatas, cciData, xVals);
                break;
            case 5:
                psyData = CalculateIndexListData.psyDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setPsyData(kLineDatas, psyData, xVals);
                break;
            case 6:
                wrData = CalculateIndexListData.wrDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setWrData(kLineDatas, wrData, xVals);
                break;
            case 7:
                dmiData = CalculateIndexListData.dmiDataCalculator(kLineDatas);//DMI指标 值
                combinedData = CombinedDataSet.setDmiData(kLineDatas, dmiData, xVals);//DMI指标 图
                break;
            case 8:
                rocData = CalculateIndexListData.rocDataCalculator(kLineDatas);//ROC指标 值
                combinedData = CombinedDataSet.setRocData(kLineDatas, rocData, xVals);
                break;
            case 9:
                trisData = CalculateIndexListData.trisDataCalculator(kLineDatas);//TRIS指标 值
                combinedData = CombinedDataSet.setTrisData(kLineDatas, trisData, xVals);
                break;
            case 10:
                sarData = CalculateIndexListData.sarDataCalculator(kLineDatas);//SAR指标 值
                combinedData = CombinedDataSet.setSarData(kLineDatas, sarData, xVals,candleEntries);
                break;
            default:
                macdData = CalculateIndexListData.macdDataCalculator(kLineDatas);
                combinedData = CombinedDataSet.setMacdData(kLineDatas, macdData, xVals);
                break;
        }
        return combinedData;
    }

注:

指标的算法和副图Chart的Data设置 在以后贴出来

3.1、下面是联动和高亮的设置以及一些效果

联动的类(这里采用内部类简单省事)


    //MyOnChartGestureListener 联动图手势监听类
    private class MyOnChartGestureListener implements OnChartGestureListener {

        private CombinedChart chartScroll;//手停留的图表,要滑动的
        private CombinedChart chartFollow;//另一个没有获取Gesture事件的 联动的图

        public MyOnChartGestureListener(CombinedChart chartScroll, CombinedChart chartFollow) {
            this.chartScroll = chartScroll;
            this.chartFollow = chartFollow;
        }
        @Override
        public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
            klineChartMaster.highlightValue(null);
            klineChartDeputy.highlightValue(null);
            setNoDataSelected();
            syncChartsMaster(chartScroll, chartFollow);

        }
        @Override
        public void onChartLongPressed(MotionEvent me) {
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartDoubleTapped(MotionEvent me) {
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartSingleTapped(MotionEvent me) {
            setNoDataSelected();
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
            syncChartsMaster(chartScroll, chartFollow);
        }
        @Override
        public void onChartTranslate(MotionEvent me, float dX, float dY) {
            onChartScrolling();//me, dX, dY
            syncChartsMaster(chartScroll, chartFollow);
        }
    }

    //处理 联动 问题
    private void syncChartsMaster(CombinedChart chartScroll, CombinedChart chartFollow) {
        Matrix srcMatrix;
        float[] srcVals = new float[9];
        Matrix dstMatrix;
        float[] dstVals = new float[9];

        // get src chart translation matrix:
        srcMatrix = chartScroll.getViewPortHandler().getMatrixTouch();
        srcMatrix.getValues(srcVals);

        dstMatrix = chartFollow.getViewPortHandler().getMatrixTouch();
        dstMatrix.getValues(dstVals);

        dstVals[Matrix.MSCALE_X] = srcVals[Matrix.MSCALE_X];
        dstVals[Matrix.MSKEW_X] = srcVals[Matrix.MSKEW_X];
        dstVals[Matrix.MTRANS_X] = srcVals[Matrix.MTRANS_X];
        dstVals[Matrix.MSKEW_Y] = srcVals[Matrix.MSKEW_Y];
        dstVals[Matrix.MSCALE_Y] = srcVals[Matrix.MSCALE_Y];// 主图高度 约是 两倍的 副图高度
        dstVals[Matrix.MTRANS_Y] = srcVals[Matrix.MTRANS_Y];
        dstVals[Matrix.MPERSP_0] = srcVals[Matrix.MPERSP_0];
        dstVals[Matrix.MPERSP_1] = srcVals[Matrix.MPERSP_1];
        dstVals[Matrix.MPERSP_2] = srcVals[Matrix.MPERSP_2];

        dstMatrix.setValues(dstVals);
        chartFollow.getViewPortHandler().refresh(dstMatrix, chartFollow, true);
    }

3.2、高亮数据设置,取消高亮设置,以及滑动过程中图表要显示值设置

    private void setParameterData(int position) {//设置 主图 MA5\MA10\MA20 的值
        if(position<0){
            return;
        }
        if (position >= kLineDatas.size()) {
            position = kLineDatas.size() - 1;
        }
        parameter_ma0.setText("MA5:" + line5Entries.get(position).getVal());
        parameter_ma1.setText("MA10:" + line10Entries.get(position).getVal());
        parameter_ma2.setText("MA20:" + line20Entries.get(position).getVal());
    }
    //指标 默认显示 指标的参数
    private String indexDefaults[] = {
                "MACD(12,26,9)", "RSI(6,12,24)", 
                "BOLL(26,2)", "KDJ(9,3,3)", "CCI(14)", 
                "PSY(12)", "WR(10,6)", "DMI(14,6)", 
                "SAR(4,2,20)", "ROC(24,20)", "TRIS(12,20)"
            };  
    private void setParameterData() { //取消高亮 副图回复默认显示        klineChartMaster.getCenterOffsets()
        parameter_index_default.setText(indexDefaults[typeIndex]);
        parameter_index0.setText("");
        parameter_index1.setText("");
        parameter_index2.setText("");
        parameter_index3.setText("");
    }
    private void setParameterDataSelected(int position) {// 设置 高亮选中的 主图 MA5\MA10\MA20 的值 和 副图的值
        if(position<0){
            return;
        }
        if (position >= kLineDatas.size()) {
            position = kLineDatas.size() - 1;
        }
        positionHighLight = position;
        parameter_ma0.setText("MA5:" + line5Entries.get(position).getVal());
        parameter_ma1.setText("MA10:" + line10Entries.get(position).getVal());
        parameter_ma2.setText("MA20:" + line20Entries.get(position).getVal());
        parameter_index_default.setText("");
        try {
            if (position > klineChartDeputy.getXValCount()) {//axisX_Deputy
                return;
            }
        } catch (NullPointerException e) {
            return;
        }
        switch (typeIndex) {
            case 0://Const.INDEX_MACD,
                parameter_index0.setText("DIF:" + macdData[0][position]);
                parameter_index1.setText(" DEA:" + macdData[1][position]);
                parameter_index2.setText(" MACD:" + macdData[2][position]);
                break;
            case 1:// Const.INDEX_RSI,
                parameter_index0.setText("RSI6:" + rsiData[0][position]);
                parameter_index1.setText(" RSI12:" + rsiData[1][position]);
                parameter_index2.setText(" RSI24:" + rsiData[2][position]);
                break;
            case 2:// Const.INDEX_BOLL,
                parameter_index0.setText("MID:" + bollData[0][position]);
                parameter_index1.setText(" UPPER:" + bollData[1][position]);
                parameter_index2.setText(" LOWER:" + bollData[2][position]);
                break;
            case 3:// Const.INDEX_KDJ,
                parameter_index0.setText("K:" + kdjData[0][position]);
                parameter_index1.setText(" D:" + kdjData[1][position]);
                parameter_index2.setText(" J:" + kdjData[2][position]);
                break;
            case 4:// Const.INDEX_CCI,
                parameter_index0.setText("CCI:" + cciData[0][position]);
                break;
            case 5:// Const.INDEX_PSY,
                parameter_index0.setText("PSY:" + psyData[0][position]);
                break;
            case 6:// Const.INDEX_WR
                parameter_index0.setText("WR10:" + wrData[0][position]);
                parameter_index1.setText(" WR6:" + wrData[1][position]);
                break;
            case 7:// Const.INDEX_DMI
                parameter_index0.setText("+DI:" + dmiData[0][position]);//+DI、—DI、ADX、ADXR
                parameter_index1.setText(" -DI:" + dmiData[1][position]);
                parameter_index2.setText(" ADX:" + dmiData[2][position]);
                parameter_index3.setText(" ADXR:" + dmiData[3][position]);
                break;
            case 8:// ROC
                parameter_index0.setText("ROC:" + rocData[0][position]);
                parameter_index1.setText("ROCMA:" + rocData[1][position]);
                break;
            case 9:// TRIC
                parameter_index0.setText("TRIX:" + trisData[0][position]);
                parameter_index1.setText(" TRMA:" + trisData[1][position]);
                break;
            case 10:// SAR
                parameter_index0.setText("SAR:" + sarData[0][position]);
                break;
            default:
                break;
        }
    }
    public void onChartScrolling() { //设置图表 滑动过程中 的要显示的数据
        visibleXIndexLeft = klineChartMaster.getLowestVisibleXIndex();// 获取视图上最左边(最小)的值得位置
        visibleXIndexRight = klineChartMaster.getHighestVisibleXIndex();// 获取视图上最右边(最大)的值得位置
        setParameterData(visibleXIndexRight);
        setNoDataSelected();
    }
    private void setNoDataSelected() { ////设置图表 停止滑动后 的要显示的数据
        isHighLightTime = false;
        klineChartMaster.highlightValue(null);
        klineChartDeputy.highlightValue(null);
        setParameterData();
        setParameterData(klineChartMaster.getHighestVisibleXIndex());//把最右边的position设置给 主图 MA5\MA10\MA20
    }

4.1、代码中的补充变量,以及handler下一篇是一些工具类

    /*
    * ButterKnife 初始化组件
    * */
    private Unbinder unBinder;//ButterKnife 绑定组件 和 解绑组件unBinder.unbind();
    @BindView(R.id.kline_chart_master)    CombinedChart klineChartMaster;//主图
    @BindView(R.id.kline_chart_deputy)    CombinedChart klineChartDeputy;//副图
    @BindView(R.id.progressBarRL)    RelativeLayout progressBarRL;//显示网络加载状态的组件
    @BindView(R.id.progressBar)    ProgressBar progressBar;
    @BindView(R.id.data2show_master)    LinearLayout data2show_master; //主图 显示MA5、MA10、MA20的 linearLayout
    @BindView(R.id.data2show_deputy)    LinearLayout data2show_deputy; //副图 显示指标参数 或者 指标数据的 linearLayout
    @BindView(R.id.parameter_ma0)    TextView parameter_ma0; //主图 显示MA5 的Textview
    @BindView(R.id.parameter_ma1)    TextView parameter_ma1; //主图 显示MA10 的Textview
    @BindView(R.id.parameter_ma2)    TextView parameter_ma2; //主图 显示MA20 的Textview
    @BindView(R.id.parameter_index_default)    TextView parameter_index_default; //副图  显示指标的默认参数 的Textview
    @BindView(R.id.parameter_index0)    TextView parameter_index0; //副图   显示指标的默认参数对应的值 的Textview
    @BindView(R.id.parameter_index1)    TextView parameter_index1; //副图  显示指标的默认参数对应的值 的Textview
    @BindView(R.id.parameter_index2)    TextView parameter_index2; //副图  显示指标的默认参数对应的值 的Textview
    @BindView(R.id.parameter_index3)    TextView parameter_index3; //副图  显示指标的默认参数对应的值 的Textview

    XAxis axisX_Master, axisX_Deputy;// 主/副 图的x轴的设置 不能加private私有化
    YAxis axisLeftMaster, axisLeftDeputy;// 主/副 图的y轴 左边的设置
    YAxis axisRightMaster, axisRightDeputy;// 主/副 图的y轴 右边的设置

    private int chartMarginRight = 120;//图表右边的距离 //DensityUtil.dip2px(getActivity(),60);//
    private int chartMarginBottom = 40;//图表底部的距离 //DensityUtil.dip2px(getActivity(),20);//

    private String code ;//
    public static  int positionDF = 2;
    public static  DecimalFormat dfs[] = {Const.df0, Const.df1, Const.df2, Const.df3, Const.df4};

    //private DataParse mData;
    private List kLineDatas;//图的数据
    private ArrayList xVals; //画 X轴 日期 的数据
    private ArrayList candleEntries; //画 蜡烛图 CMA5线 的数据
    private ArrayList line5Entries; //画 CMA5线 的数据
    private ArrayList line10Entries; //画 CMA10线 的数据
    private ArrayList line20Entries; //画 CMA20线 的数据

    //一些颜色值的初始化,把原本可以改变 黑白色主题切换去掉了,保留默认的黑色主题
    private int BG_COLOR = Color.parseColor("#1b1c21");//  整个K线的背景颜色,  // DashedLineLength
    private final float DASHED_LENGTH_LINE = 6f;//  虚线的长度  // DashedLineLength
    private final float DASHED_LENGTH_SPACE = 6f;//  虚线的长度  // DashedLineLength
    private final float DECELERATION_FRICTION_COEFFICIENT = 0.4f;//  DecelerationFrictionCoefficient  //减速摩擦系数在[ 0;1 ]区间,较高的值显示的速度就会慢慢减少,例如,如果设置为0,它将立即停止。1是一个无效的值,并将自动转换为0.999f。
    private final float MATRIX_SCALE_X = 4.0f;//用于设置图表 单个图的
    private final float MATRIX_SCALE_Y = 1.0f;//
    private final int COLOR_WHITE = 0xffffffff;//Color.parseColor("#FFe32222");//                   //Color.rgb(37, 155, 36); // #259B24 // 深绿色
    private int COLOR_TEXT_DEFAULT = Color.parseColor("#c8cfe5"); // 008D93默认 参考值 显示的颜色 // 858fb3 Color.GRAY;
    private int COLOR_TEXT_HIGH_LIGHT = Color.parseColor("#c8cfe5");// 长按 提示线 显示的颜色 // 1f2e5b
    private int COLOR_LINE_DEFAULT = Color.parseColor("#2d2f3a");// 默认 参考线 显示的颜色
    public static int COLOR_LINE_HIGH_LIGHT = Color.parseColor("#2d2f3a");// 长按 提示线 显示的颜色 // 1f2e5b

    private int typeTime = 6;//日K    [0-8]
    private String formatDate = "yyyy-MM-dd HH:mm:ss";
    private int typeIndex = 0;

    private final int CMA5 = 5;
    private final int CMA10 = 10;
    private final int CMA20 = 20;
    private final int CMAs[] = { CMA5, CMA10, CMA20 };

    private PriceData timeNow_UDP;// 当前数据
    private boolean isHighLightTime = false;//是否是十字光标 高亮的状态
    private int positionHighLight ;//是否是十字光标 选中的位置

    private int visibleXIndexLeft = 0;//图表停下来时候 显示的最左边的位置
    private int visibleXIndexRight = 0;//记录当前右边移动的position 图表停下来时候 显示的最右边的位置

    private final int CHART_NOTIFY_DATA = 0x111;
    private final int CHART_NOTIFY_DATA_AGAIN = 0x222;
    private final int LIST_REFRESH = 0x333;
    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //logChartData();
            switch (msg.what) {
                case CHART_NOTIFY_DATA:
                    klineChartMaster.notifyDataSetChanged();// 重新更新显示
                    klineChartDeputy.notifyDataSetChanged();
                    klineChartMaster.invalidate();// 重新更新显示
                    klineChartDeputy.invalidate();
                    //logChartData();
                    break;
                case CHART_NOTIFY_DATA_AGAIN:
                    klineChartDeputy.notifyDataSetChanged();
                    klineChartDeputy.invalidate();// refreshMaster
                    break;
                case LIST_REFRESH://
                    /*
                        公司的接口不能泄漏,签了保密协议的,想必大家理解。
                        可以 handler.sendEmptyMessageDelayed(LIST_REFRESH,1000);
                        每秒更新或者插入数据(真实的是每秒有十几二十条,有的有上百条数据)
                        里面的数据可以改成KLineBean这个类  我这里就不改了,想了解推送的更新数据的可以自己调整一下
                    * */
                    if (msg.obj != null && ((PriceData) msg.obj).getPrice_code() != null) {
                        if (code.equals(((PriceData) msg.obj).getPrice_code())) {
                            timeNow_UDP = (PriceData) msg.obj;
                            showNew(timeNow_UDP);
                        }
                    }
                    break;
                default:
                    break;
            }
        }
    };
    private static Utils util = new Utils();
    Activity activity;

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            this.activity = activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnUDPListener,loadDataListener");
        }
    }

布局和fragment所有的代码都在上面了

(第一次写博客,中的代码添加也是折腾了一番才出来的。有什么错误欢迎指点)

你可能感兴趣的:(股票行情图:一个fragment画K线主副图)