Skip to content

Canvas 是 Android 绘图的核心载体,相当于“画布”,所有图形(矩形、线段、路径等)都通过 Canvas 的 API 绘制到 View 上。

一、Canvas 基础认知

1. 核心作用

  • 提供各类绘图方法(画矩形、线段、路径、文字等);
  • 承载绘图的“图层”,支持平移、缩放、旋转等变换(本文聚焦基础绘制,变换后续扩展);
  • 必须在 View.onDraw(Canvas canvas) 方法中使用(系统会自动传入 Canvas 对象)。

2. 与 Paint 的关系

  • Canvas:“画布”—— 决定“画什么形状”(矩形/线段/路径);
  • Paint:“画笔”—— 决定“怎么画”(颜色、粗细、填充/描边、抗锯齿等);
  • 核心公式:Canvas.drawXXX(形状参数, Paint),二者必须配合使用。

二、关键基础:坐标体系

Android 绘图的坐标规则直接影响 K 线图的“价格-像素”映射,必须牢记:

  1. 原点 (0,0):View 的 左上角
  2. X 轴:向右为正方向(符合日常视觉,K 线从左到右排列);
  3. Y 轴:向下为正方向(与数学坐标系相反!关键区别);
  • 例:K 线图中“高价在上、低价在下”,需通过公式转换(如 K 线图中 priceToY 方法)。

坐标映射实战(K 线图核心)

K 线图中“价格 → Y 轴像素”的逻辑,正是基于坐标体系设计:

// 价格越高,Y 轴像素值越小(越靠上)
private float priceToY(float price, float height) {
    if (mMaxPrice == mMinPrice) return 0;
    // 公式逻辑:(最高价 - 当前价) 决定“距离顶部的比例”,再乘以 View 高度
    return height * (mMaxPrice - price) / (mMaxPrice - mMinPrice);
}

三、K 线图常用 Canvas API(实战重点)

1. 绘制矩形(K 线实体)

  • 用途:绘制 K 线的“开盘价-收盘价”实体部分;

  • API:canvas.drawRect(float left, float top, float right, float bottom, Paint paint)

  • 参数说明:

  • left:矩形左边界 X 坐标;

  • top:矩形上边界 Y 坐标(注意:Y 轴向下为正,所以“上方”的 Y 值更小);

  • right:矩形右边界 X 坐标;

  • bottom:矩形下边界 Y 坐标;

  • 实战注意:

  • 需确保 top < bottom(K 线实体是有效矩形),所以取 openclose 对应的 Y 值的 min/max;

  • 涨跌幅为 0 时(top == bottom),强制 bottom += 1f,避免矩形消失。

2. 绘制线段(K 线影线)

  • 用途:绘制 K 线的“最高价-最低价”影线(竖线);

  • API:canvas.drawLine(float startX, float startY, float endX, float endY, Paint paint)

  • 参数说明:

  • startX/startY:线段起点坐标;

  • endX/endY:线段终点坐标;

  • 实战技巧:

  • K 线影线需“居中”,所以 X 坐标取 K 线的中心线(xCenter = xLeft + mCandleWidth / 2f);

  • 起点是最高价对应的 Y 值(yHigh,更靠上,Y 更小),终点是最低价对应的 Y 值(yLow,更靠下,Y 更大)。

3. 绘制路径(均线)

  • 用途:绘制 MA5/MA10 等连续均线(需连接多个点);
  • 核心类:Path(记录连续的坐标点,形成路径);
  • 常用 API 组合:
  1. Path.moveTo(float x, float y):设置路径起点(第一个均线点);
  2. Path.lineTo(float x, float y):添加路径后续点(后续均线点,自动与上一个点连接);
  3. canvas.drawPath(Path path, Paint paint):绘制完整路径;
  • 实战优势:

  • 比循环调用 drawLine 更高效(一次性绘制连续线段);

  • 路径更顺滑,避免线段断裂(适合均线、趋势线等连续图形)。

4. 绘制背景(基础铺垫)

  • 用途:设置 K 线图的黑色背景;
  • API:canvas.drawColor(int color)canvas.drawARGB(int a, int r, int g, int b)
  • 注意:需在绘制其他图形前调用(先铺背景,再画前景内容)。

四、Paint 关键配置(影响绘制效果)

K 线图中用到的 Paint 配置,覆盖核心属性:

Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 抗锯齿(必加,避免图形边缘毛刺)
paint.setColor(Color.RED); // 颜色(涨红跌绿、均线黄/紫)
paint.setStyle(Paint.Style.FILL); // 填充模式(K 线实体用 FILL,均线用 STROKE)
paint.setStyle(Paint.Style.STROKE); // 描边模式(仅画轮廓,适合线段、路径)
paint.setStrokeWidth(2f); // 线条宽度(影线、均线的粗细)

关键属性说明:

  • ANTI_ALIAS_FLAG:抗锯齿,必须开启(否则 K 线、均线边缘会有锯齿,影响视觉);

  • Style

  • FILL:填充(矩形内部上色,适合 K 线实体);

  • STROKE:仅描边(适合线段、均线,不填充内部);

  • StrokeWidth:线条粗细,数值越大越粗(均线用 3f,影线用 2f,根据需求调整)。

五、K 线图绘制流程(串联 Canvas 核心用法)

  1. 初始化画布:canvas.drawColor(Color.BLACK) 铺黑色背景;
  2. 计算参数:可视区域 K 线数量、最高价/最低价(适配 Y 轴);
  3. 绘制 K 线:
  • 循环遍历可视区域的 K 线数据;
  • 计算每个 K 线的 X 边界(左/右)、Y 坐标(开/收/高/低);
  • drawLine 画影线,drawRect 画实体;
  1. 绘制均线:
  • Path 记录所有均线点(moveTo 起点 + lineTo 后续点);
  • drawPath 一次性绘制 MA5/MA10;
  1. 刷新画布:通过 invalidate() 触发 onDraw 重绘(手势滑动/缩放后调用)。

六、常见坑与注意事项6

  1. 坐标计算错误:忘记 Y 轴向下为正,导致价格映射颠倒(高价在下、低价在上);
  2. 除零错误:计算 priceToY 时,需判断 mMaxPrice == mMinPrice(避免除零);
  3. 图形超出屏幕:未计算可视区域的最高/最低价,导致 K 线或均线超出 View 范围;
  4. 绘制顺序:先画背景,再画 K 线,最后画均线(避免被遮挡);
  5. 性能优化:避免在 onDraw 中创建对象(如 Paint、Path),需提前初始化(K 线图中已做到)。

Released under the MIT License.