如何绘制虚线
======

#### 问题现象

页面中如何绘制虚线作为边框或分隔线？

#### 效果预览

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/3c/v3/YaTL2OTkRFOPsEFKAC2-RQ/zh-cn_image_0000002628553240.png?HW-CC-KV=V1&HW-CC-Date=20260709T134301Z&HW-CC-Expire=86400&HW-CC-Sign=620224639614023D47EF4399024A6D6A9860C7DE4FC1F20247D3958E9EF56DBF "点击放大")

#### 背景知识

[Divider](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-basic-components-divider)组件能够分隔不同内容块或内容元素，可以在视觉上界定内容区域和引导用户视线移动，例如，使用垂直虚线分隔列，可以使用户更清晰地查看每一列的内容，同时保持整体的简洁感。Divider除通用属性外，还支持以下四个属性：

*   [border](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#border)属性可以为组件实现边框样式。其对象参数[BorderOptions](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-types#borderoptions)中的style设置为Dashed时，显示为一系列短的方形虚线；dashGap可以控制虚线的间距。

*   除border这一属性外，也可以通过[borderStyle](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderstyle)，[borderWidth](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderwidth)，[borderColor](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#bordercolor)，[borderRadius](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#borderradius)几个属性组合实现虚线的边框样式，从效果上来看，这几个属性都相当于BorderOptions的具体内容。
*   [Canvas](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-components-canvas-canvas)是一种画布组件，用于自定义绘制图形，绘制对象可以是基础形状、文本、图片等，[CanvasRenderingContext2D](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-canvasrenderingcontext2d)是该组件的参数，开发者可使用它于Canvas组件上进行绘制。
*   [setLineDash](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-canvasrenderingcontext2d#setlinedash)是CanvasRenderingContext2D组件的方法，可用于设置画布的虚线样式。

#### 解决方案

*   **方案一**：通过给Divider设置borderStyle+borderWidth属性或border属性实现。可参考官网示例[示例1（基本样式用法）](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-universal-attributes-border#示例1基本样式用法)。
*   **方案二**：通过Canvas绘制。
    
    border属性仅能设置间隔长度均匀的虚线，如果需要绘制间隔长度不均匀的虚线，需要Canvas实现。
    
    1.  创建Canvas组件，传入CanvasRenderingContext2D对象。
        
        Canvas(this.context)
          .width('100%')
          .height('100%')
          .onReady(() \=\> {
            this.context.lineWidth \= 1;
            this.context.strokeStyle \= 'black';
           _ // 用户可在这自定义虚线的样式_
            this.context.setLineDash(\[10, 20, 30, 40, 50, 40, 30, 20, 10\]);
            this.wrapText(0, 40, this.context.width);
          });
        
    2.  使用context的setLineDash方法，该方法会传入一个number数组，分别交替表示虚线的长度以及虚线的间隔，如果遍历完数组后虚线未达到屏幕的边缘，则会重新遍历数组继续绘制。
        
        this.context.setLineDash(\[10, 20, 30, 40, 50, 40, 30, 20, 10\]);
        
    3.  使用context的stroke方法进行绘制。
        
        wrapText(x: number, y: number, maxWidth?: number) {
          this.context.beginPath();
          this.context.moveTo(x, y \+ 10);
          this.context.lineTo(maxWidth, y \+ 10);
          this.context.stroke();
          this.context.closePath();
        }
        
    4.  完整示例参考如下：
        
        @Entry
        @Component
        struct DashedLine {
          private settings: RenderingContextSettings \= new RenderingContextSettings(true);
          private context: CanvasRenderingContext2D \= new CanvasRenderingContext2D(this.settings);
        
          wrapText(x: number, y: number, maxWidth?: number) {
            this.context.beginPath();
            this.context.moveTo(x, y \+ 10);
            this.context.lineTo(maxWidth, y \+ 10);
            this.context.stroke();
            this.context.closePath();
          }
          build() {
            Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
              Canvas(this.context)
                .width('100%')
                .height('100%')
                .onReady(() \=\> {
                  this.context.lineWidth \= 1;
                  this.context.strokeStyle \= 'black';
                _  // 用户可在这自定义虚线的样式_
                  this.context.setLineDash(\[10, 20, 30, 40, 50, 40, 30, 20, 10\]);
                  this.wrapText(0, 40, this.context.width);
                });
            }
            .width('100%')
            .height('100%');
          }
        }