想画圆角卡片和按钮?RoundRect 让你轻松搞定

在 APP 开发中,圆角矩形可能是最常见的 UI 元素了——卡片、按钮、输入框、头像框,几乎到处都是圆角。在 HarmonyOS 的 drawing 模块里,RoundRect 类就是专门用来创建和操作圆角矩形的。

RoundRect 是什么?

简单说,RoundRect 就是一个"圆角矩形对象"。它在普通矩形的基础上,给四个角加上了圆角效果。你可以控制每个角的圆角半径,甚至让四个角的半径都不一样。

打个比方:普通矩形就像一块方方正正的砖头,RoundRect 就像一块被磨圆了角的鹅卵石。磨多大、磨哪个角,都由你来定。

创建一个圆角矩形

下面的流程图展示了 RoundRect 的创建和绘制完整流程:

定义矩形区域Rect

创建RoundRect对象

是否需要不同圆角?

使用统一圆角半径

用setCorner设置各角半径

左上角: TOP_LEFT_POS

右上角: TOP_RIGHT_POS

左下角: BOTTOM_LEFT_POS

右下角: BOTTOM_RIGHT_POS

创建Brush填充

Canvas.drawRoundRect绘制填充

创建Pen描边

Canvas.drawRoundRect绘制边框

最基本的创建方式是传入一个矩形区域和圆角半径:

import { common2D, drawing } from '@kit.ArkGraphics2D';

let rect: common2D.Rect = {left : 100, top : 100, right : 500, bottom : 300};
let roundRect = new drawing.RoundRect(rect, 50, 50);

这里有两个圆角半径参数:

xRadii:X 轴方向的圆角半径。值越大,圆角越"圆"。

yRadii:Y 轴方向的圆角半径。

为什么要分 X 和 Y 两个方向呢?因为你可以做出"椭圆形"的圆角效果。如果 xRadii 和 yRadii 相等,就是标准的圆角;如果不等,圆角就会变成椭圆弧。

有个重要规则:只有当 xRadii 和 yRadii 都大于 0 的时候,圆角才会生效。如果你传了 0 或负数,那创建出来的就是一个普通的直角矩形。

复制一个圆角矩形

从 API version 20 开始,你可以用拷贝构造函数来复制一个已有的圆角矩形:

import { common2D, drawing } from '@kit.ArkGraphics2D';

let rect: common2D.Rect = {left : 100, top : 100, right : 500, bottom : 300};
let roundRect = new drawing.RoundRect(rect, 50, 50);
let roundRect2 = new drawing.RoundRect(roundRect);

roundRect2roundRect 的一个副本,修改其中一个不会影响另一个。这在你需要基于一个基础样式创建多个变体时很有用。

给每个角设置不同的半径:setCorner

这是 RoundRect 最灵活的功能。你可以单独给四个角设置不同的圆角半径:

import { drawing } from '@kit.ArkGraphics2D';

let roundRect : drawing.RoundRect = new drawing.RoundRect({left: 0, top: 0, right: 300, bottom: 300}, 50, 50);
roundRect.setCorner(drawing.CornerPos.TOP_LEFT_POS, 150, 150);

setCorner 的第一个参数是角的位置,用 CornerPos 枚举来指定:

  • TOP_LEFT_POS:左上角
  • TOP_RIGHT_POS:右上角
  • BOTTOM_LEFT_POS:左下角
  • BOTTOM_RIGHT_POS:右下角

后面两个参数是这个角在 X 和 Y 方向上的圆角半径。

实际用途举例

想做一个"对话气泡"效果,只有左上角是尖的,其他三个角是圆的?

let roundRect = new drawing.RoundRect({left: 0, top: 0, right: 200, bottom: 100}, 10, 10);
roundRect.setCorner(drawing.CornerPos.TOP_LEFT_POS, 0, 0); // 左上角不要圆角

想做一个"标签页"效果,只有上面两个角是圆的?

let roundRect = new drawing.RoundRect({left: 0, top: 0, right: 200, bottom: 50}, 10, 10);
roundRect.setCorner(drawing.CornerPos.BOTTOM_LEFT_POS, 0, 0);
roundRect.setCorner(drawing.CornerPos.BOTTOM_RIGHT_POS, 0, 0);

读取某个角的半径:getCorner

想知道某个角当前的圆角半径是多少?用 getCorner

import { drawing } from '@kit.ArkGraphics2D';

let roundRect : drawing.RoundRect = new drawing.RoundRect({left: 0, top: 0, right: 300, bottom: 300}, 50, 50);
let cornerRadius = roundRect.getCorner(drawing.CornerPos.BOTTOM_LEFT_POS);
console.info("getCorner---"+cornerRadius.x)
console.info("getCorner---"+cornerRadius.y)

返回的是一个 Point 对象,x 是 X 方向的半径,y 是 Y 方向的半径。

移动圆角矩形:offset

offset 方法可以让整个圆角矩形在画布上平移:

import { drawing } from '@kit.ArkGraphics2D';

let roundRect : drawing.RoundRect = new drawing.RoundRect({left: 0, top: 0, right: 300, bottom: 300}, 50, 50);
roundRect.offset(100, 100);

offset(100, 100) 表示向右移动 100px,向下移动 100px。传负数就是往反方向移动。

这个方法直接修改的是 RoundRect 对象本身的位置,不会改变它的大小和圆角半径。

怎么把 RoundRect 画出来?

创建好 RoundRect 之后,你需要用 Canvas 来绘制它。基本流程是:

  1. 创建 RoundRect 对象
  2. 创建 Brush 或 Pen
  3. 用 Canvas 的 drawRoundRect 方法绘制
import { RenderNode } from '@kit.ArkUI';
import { common2D, drawing } from '@kit.ArkGraphics2D';

class DrawingRenderNode extends RenderNode {
  draw(context : DrawContext) {
    const canvas = context.canvas;
    // 创建圆角矩形
    let roundRect = new drawing.RoundRect({left: 50, top: 50, right: 350, bottom: 200}, 20, 20);
    // 创建画刷
    let brush = new drawing.Brush();
    brush.setColor({alpha: 255, red: 100, green: 150, blue: 255});
    canvas.attachBrush(brush);
    // 绘制填充的圆角矩形
    canvas.drawRoundRect(roundRect);
    // 创建画笔画边框
    let pen = new drawing.Pen();
    pen.setColor({alpha: 255, red: 0, green: 0, blue: 0});
    pen.setStrokeWidth(2);
    canvas.attachPen(pen);
    canvas.drawRoundRect(roundRect);
  }
}

这段代码先用蓝色 Brush 填充圆角矩形,再用黑色 Pen 描边,做出了一个带边框的蓝色圆角卡片效果。

实际应用场景

下面的流程图展示了不同场景下圆角半径的选择策略:

小按钮/输入框

卡片/对话框

突出卡片/模态框

头像/标签

对话气泡

标签页

选择圆角半径

UI元素类型

4-8px轻微圆角

12-16px标准圆角

20-30px大圆角

宽高一半: 圆形/胶囊形

三圆角+一直角

setCorner设置一个角半径为0

上两角圆+下两角直

setCorner设置下两角半径为0

场景一:卡片式布局

现在几乎所有 APP 都用卡片式设计。用 RoundRect 可以轻松创建各种卡片:

// 标准圆角卡片
let card = new drawing.RoundRect({left: 20, top: 20, right: 380, bottom: 200}, 12, 12);

// 大圆角卡片(更"胖"的感觉)
let bigCard = new drawing.RoundRect({left: 20, top: 20, right: 380, bottom: 200}, 24, 24);

// 胶囊按钮(圆角半径等于高度的一半)
let capsule = new drawing.RoundRect({left: 20, top: 20, right: 180, bottom: 70}, 25, 25);

场景二:头像框

圆形头像框其实就是圆角半径足够大的正方形:

// 100x100 的正方形,圆角半径 50,就是圆形
let avatarFrame = new drawing.RoundRect({left: 0, top: 0, right: 100, bottom: 100}, 50, 50);

场景三:对话气泡

微信风格的对话气泡,一边是圆角,一边有个小尖角:

let bubble = new drawing.RoundRect({left: 0, top: 0, right: 200, bottom: 80}, 10, 10);
bubble.setCorner(drawing.CornerPos.TOP_LEFT_POS, 0, 0); // 左上角不圆

场景四:进度条背景

圆角进度条的背景:

let progressBg = new drawing.RoundRect({left: 20, top: 100, right: 380, bottom: 120}, 10, 10);

圆角半径的选择建议

  • 4-8px:轻微圆角,适合小按钮、输入框
  • 12-16px:标准圆角,适合卡片、对话框
  • 20-30px:大圆角,适合突出的卡片、模态框
  • 等于宽高的一半:圆形/胶囊形,适合头像、标签

注意事项

  1. API 版本:RoundRect 从 API version 12 开始支持,拷贝构造函数从 API version 20 开始。

  2. 半径必须大于 0:如果 xRadii 或 yRadii 小于等于 0,圆角不会生效,会变成普通矩形。

  3. 物理像素:所有尺寸单位都是物理像素 px。

  4. 线程安全:和其他 drawing 对象一样,是单线程模型。

  5. 半径不能超过短边的一半:如果圆角半径超过了矩形短边长度的一半,实际效果会被限制在短边的一半。

小结

RoundRect 是 drawing 模块里专门处理圆角矩形的工具类。它的核心功能就是创建圆角矩形,然后你可以用 setCorner 给每个角设置不同的半径,用 offset 来移动位置。

虽然功能看起来简单,但在实际 APP 开发中,圆角矩形的使用频率非常高。掌握了 RoundRect,你就能轻松实现各种卡片、按钮、对话框的绘制了。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐