股票行情图的绘制,分时图和闪电图

心血来潮,想到去年独立开发的一个项目XX操盘,其中有关于个股的走势行情图是完全基于自定义view实现的,本文分析一下大致流程及部分实现代码;具体的自定义控件步骤想必大家比我还清楚的,不作详解


分时图

效果图如下(分时图暂未录制动图,闪电动图在最后哦~~~)
分时图背景闭合

实现步骤:

1.自定义相关属性:attrs.xml中声明
<declare-styleable name="MinView">
    <attr name="pathColor" format="reference|color"/>
    <attr name="textDColor" format="reference|color"/>
    <attr name="lineColorr" format="reference|color"/>
    <attr name="fillPathColorr" format="reference|color"/>
    <attr name="textSizz" format="dimension"/>
</declare-styleable>
2.布局中引用 com.domain.my.MinView
3.获取属性 constructor method
4.测量view设置大小
/**
  * 根据测量模式得到view的宽和高
  * @param widthMeasureSpec
  * @param heightMeasureSpec
  */
 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     super.onMeasure(widthMeasureSpec, heightMeasureSpec);
     measuredWidth = getMeasuredWidth();
     measuredHeight = getMeasuredHeight();
     int widhtSpecMode = MeasureSpec.getMode(widthMeasureSpec);
     int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
     mChartLeftMargin = getLeft() + getPaddingLeft();
     mChartRightMargin = getPaddingRight();

     if (widhtSpecMode == MeasureSpec.EXACTLY) {
         mViewWidth = measuredWidth - mChartRightMargin - mChartLeftMargin;//view的宽度
     }
     if (heightSpecMode == MeasureSpec.EXACTLY) {
         mViewHeight = measuredHeight - getPaddingBottom() - getPaddingTop() - mTextHeight;//view的高度
         mBottomTextTop = mChartHeight + mTextMargin;
     }
 }
5. 绘制onDraw(Canvas canvas)
//1,绘制view背景
canvas.drawRect(0, 0, measuredWidth, measuredHeight, mPaintBg);
//2,画坐标虚线
drawDashLine(canvas);
//3,画右侧文字
drawRText(canvas);
//4,绘制走势路径
if (futures != null && futures.size() > 0)
   drawPath(canvas);

/**
* 画坐标横线
* @param canvas
*/
private void drawDashLine(Canvas canvas) {
   startY = mTextMargin;
   mPath.reset();
   if (datas == null)
       throw new RuntimeException("data is null");
   for (int index = 0; index < mLineNum; index++) {
       mPath.moveTo(0, startY);
       mPath.lineTo(0 + mLineWidth, startY);
       startY += mLineSpaceX;
   }
   canvas.drawPath(mPath, mAxisPaint);
}

/**
 * 画右侧坐标上的文字,需注意初始化无数据默认为0.0
 * @param canvas
 */
private void drawRText(Canvas canvas) {
    startY = mTextMargin;
    for (int index = 0; index < mLineNum; index++) {
        if (datas == null)
            break;
        if (futures != null && futures.size() > 0)
            canvas.drawText(datas.get(index), mChartWidth - mTextWidth, startY + mTextHeight / 2, mTextPaint);
        else
            canvas.drawText(datas.get(index), mChartWidth - mTextWidth, startY + mTextHeight / 2, mTextPaint);
        startY += mLineSpaceX;
    }
}

/**
 * 走势图实现,通过path绘制数据路径
 */
private void drawPath(Canvas canvas) {
    mPath1.reset();//重置路径,避免path数据过多消耗过多内存
    mPath2.reset();
    mLastX = 0;
    mLastY = getActualY(futures.get(0).getCurrent());

    mPath1.moveTo(mLastX, mLastY);
    mPath2.moveTo(mLastX, mChartHeight);
    mPath2.lineTo(mLastX, mLastY);

    for (int i = 0; i < futures.size(); i++) {
        toY = getActualY(futures.get(i).getCurrent());
        mPath1.lineTo(mLastX, toY);
        mPath2.lineTo(mLastX, toY);
        mLastX = i * mAxisIndex;
    }
    canvas.drawPath(mPath1, mPathPaint);//明线路径
    canvas.drawPath(mPath2, mFillPaint);//闭合区域与坐标轴的背景
}

以上就是绘制分时图的核心代码,其中关于使用到的行情数据不便提供,其他的有关画笔变量的初始化及自定义属性获取,控件的使用设置等都比较容易,可以自行体验。

需注意使用path在绘制大量数据的时候很容易内存泄露,导致绘制卡顿,处理方式代码中已给出,注意即可。

闪电图电流走动一般的效果

  • 闪电图经
    闪电图

  • 闪电图动图

    某品种闪电走势图

闪电图的实现方式同分时图,就不上重复代码了,区别在于闪电走势到画布最后需要有动态的移位效果,用到了画布的canvas.translate(-translateX, 0);画布向左移动才有上图的效果,可自行学习实现。

END—-

K线图原理同上,与分时图不同,K线绘制的是一个个小矩形(包括底部交易量),后续可补上。

猜你喜欢

转载自blog.csdn.net/NatanLu/article/details/78808941