金融类自定义View--股票分时图
2017-11-25 22:41 阅读(251)

金融类自定义View–股票分时图

本节主要介绍股票分时图的详细实现思路与遇到的各种问题。该分时图主要包括以下功能:数据的适配、x/y背景轴的绘制、x/轴文字的绘制、长按十字的处理、实时折线的处理、分时折线的左右滑动等。主要会陈述的问题:如何实现最新数据横线的实现、实时数据导致折线的变化的实现思路、折线图左右滑动的处理。(参考阅读:百度百科–分时图

前言

效果图

原【天厚实盘】分时图

https://raw.githubusercontent.com/scsfwgy/FinancialCustomerView/timesharing/img/%E5%A4%A9%E5%8E%9A%E5%AE%9E%E7%9B%98_%E5%88%86%E6%97%B6%E5%9B%BE_%E9%BB%98%E8%AE%A4.png

https://raw.githubusercontent.com/scsfwgy/FinancialCustomerView/timesharing/img/%E5%A4%A9%E5%8E%9A%E5%AE%9E%E7%9B%98_%E5%88%86%E6%97%B6%E5%9B%BE_%E9%95%BF%E6%8C%89.png

https://github.com/scsfwgy/FinancialCustomerView/blob/timesharing/img/%E5%A4%A9%E5%8E%9A%E5%AE%9E%E7%9B%98_%E6%BB%91%E5%8A%A8%E6%93%8D%E4%BD%9C.gif?raw=true

仿分时图【TimeSharingView.java】

https://github.com/scsfwgy/FinancialCustomerView/blob/timesharing/img/v1.2_%E5%88%86%E6%97%B6%E5%9B%BE_%E6%8A%98%E7%BA%BF%E5%9B%BE%E9%9B%8F%E5%BD%A2.png?raw=true

https://raw.githubusercontent.com/scsfwgy/FinancialCustomerView/timesharing/img/v1.2_%E5%88%86%E6%97%B6%E5%9B%BE_%E6%8A%98%E7%BA%BF%E5%9B%BE%E9%9B%8F%E5%BD%A2_%E5%AE%8C%E5%96%84.png

https://raw.githubusercontent.com/scsfwgy/FinancialCustomerView/timesharing/img/%E5%88%86%E6%97%B6%E5%9B%BE_%E7%AC%AC%E4%B8%89%E9%98%B6%E6%AE%B5_%E5%AE%9E%E6%97%B6%E6%95%B0%E6%8D%AE%E6%98%BE%E7%A4%BA.gif

https://github.com/scsfwgy/FinancialCustomerView/blob/timesharing/img/%E5%88%86%E6%97%B6%E5%9B%BE_%E5%8F%AF%E4%BB%A5%E9%95%BF%E6%8C%89_%E5%8F%AF%E4%BB%A5%E5%B7%A6%E5%8F%B3%E6%8B%96%E5%8A%A8.gif?raw=true

主要运用什么知识

参考

数据量和位置的确认

/**
     * 实时推送过来的数据,实时更新
     *
     * @param quotes
     */
    public void addTimeSharingData(Quotes quotes) {
        if (quotes == null) {
            Toast.makeText(mContext, "数据异常", Toast.LENGTH_SHORT).show();
            Log.e(TAG, "setTimeSharingData: 数据异常");
            return;
        }
        mQuotesList.add(quotes);
        //如果实在左右移动,则不去实时更新K线图,但是要把数据加进去
        if (mPullType == PullType.PULL_NONE) {
            Log.e(TAG, "addTimeSharingData: 处理实时更新操作...");
            counterBeginAndEndByNewer();
            processData();
        }
    }

折线图的绘制和折线图阴影的处理

//折线图绘制核心代码
     private void drawBrokenLine(Canvas canvas) {
            //先画第一个点
            Quotes quotes = mQuotesList.get(mBeginIndex);
            Path path = new Path();
            Path path2 = new Path();
            //这里需要说明一下,x轴的起始点,其实需要加上mPerX,但是加上之后不是从起始位置开始,不好看。
            // 同理,for循环内x轴其实需要(i+1)。现在这样处理,最后会留一点空隙,其实挺好看的。
            float floatY = (float) (mHeight - mPaddingBottom - mInnerBottomBlankPadding - mPerY * (quotes.c - mMinQuotes.c));
            //在自定义view:FundView中的位置坐标
            //记录下位置信息
            quotes.floatX = mPaddingLeft;
            quotes.floatY = floatY;
            path.moveTo(mPaddingLeft, floatY);
            path2.moveTo(mPaddingLeft, floatY);
            for (int i = mBeginIndex + 1; i < mEndIndex; i++) {
                Quotes q = mQuotesList.get(i);
                float floatX2 = mPaddingLeft + mPerX * (i - mBeginIndex);//注意这个 mPerX * (i-mBeginIndex),而不是mPerX * (i)
                float floatY2 = (float) (mHeight - mPaddingBottom - mInnerBottomBlankPadding - mPerY * (q.c - mMinQuotes.c));
                //记录下位置信息
                q.floatX = floatX2;
                q.floatY = floatY2;
                path.lineTo(floatX2, floatY2);
                path2.lineTo(floatX2, floatY2);
                //最后一个点,画一个小圆点;实时横线;横线的右侧数据与背景;折线下方阴影
                if (i == mEndIndex - 1) {
                    //绘制小圆点
                    canvas.drawCircle(floatX2, floatY2, mDotRadius, mDotPaint);

                    //接着画实时横线
                    canvas.drawLine(mPaddingLeft, floatY2, mWidth - mPaddingRight, floatY2, mTimingLinePaint);

                    //接着绘制实时横线的右侧数据与背景
                    //文字高度
                    float txtHight = getFontHeight(mTimingTxtWidth, mTimingTxtBgPaint);
                    //绘制背景
                    canvas.drawRect(mWidth - mPaddingRight, floatY2 - txtHight / 2, mWidth, floatY2 + txtHight / 2, mTimingTxtBgPaint);

                    //绘制实时数据
                    //距离左边的距离
                    float leftDis = 8;
                    canvas.drawText(FormatUtil.numFormat(q.c, mDigits), mWidth - mPaddingRight + leftDis, floatY2 + txtHight / 4, mTimingTxtPaint);

                    //在这里把path圈起来,添加阴影。特别注意,这里处理下方阴影和折线边框。采用两个画笔和两个Path处理的,貌似没有一个Paint可以同时绘制边框和填充色
                    path2.lineTo(floatX2, mHeight - mPaddingBottom);
                    path2.lineTo(mPaddingLeft, mHeight - mPaddingBottom);
                    path2.close();
                }
            }
            canvas.drawPath(path, mBrokenLinePaint);
            canvas.drawPath(path2, mBrokenLineBgPaint);
        }1

折线图的左右滑动处理