1. Polyline 是什麼?
Polyline 是 ArkUI 提供的 折線繪製組件,簡單説就是:給它一串點座標,它會按順序把這些點用線段連起來。
特點:
- 支持 任意多個點,適合繪製路徑、折線圖、軌跡線等;
-
可以控制:
- 寬高(繪製區域);
- 線條顏色、粗細、透明度;
- 虛線樣式(線段長度/間隔長度);
- 拐角樣式(圓角 / 斜接 / 斜切);
- 端點樣式(方頭 / 圓頭等);
- 抗鋸齒;
- 支持
attributeModifier動態更新屬性(API 18+); - 支持通過
AttributeUpdater.updateConstructorParams更新構造參數(API 20+)。
基礎信息:
- 組件名:
Polyline - 子組件:無(它就是繪製一條線,不是容器)
-
支持版本:
- API 7 起支持;
- ArkTS 卡片支持:API 9+;
- 元服務 API:API 11+;
PolylineOptions標準化:API 18+;updateConstructorParams:API 20+。
適用場景舉例:
- 簡單折線圖、趨勢線;
- 地圖/路徑軌跡(示意);
- 裝飾線條(例如波浪線、路線引導);
- 連線類交互(比如“步驟 1→2→3”的可視化)。
2. 快速上手:畫兩條折線試試
先不想太多,把它畫出來再説。
// xxx.ets
@Entry
@Component
struct PolylineQuickStart {
build() {
Column({ space: 12 }) {
// 第一條:藍色細折線
Polyline({ width: 100, height: 100 })
.points([[0, 0], [20, 60], [100, 100]])
.fillOpacity(0) // 不填充區域
.stroke(Color.Blue) // 線條顏色
.strokeWidth(3) // 線寬
// 第二條:紅色粗折線,圓角+圓頭
Polyline()
.width(100)
.height(100)
.points([[20, 0], [0, 100], [100, 90]])
.fillOpacity(0)
.stroke(Color.Red)
.strokeWidth(8)
.strokeLineJoin(LineJoinStyle.Round) // 拐角圓角
.strokeLineCap(LineCapStyle.Round) // 兩端圓頭
}
.width('100%')
.margin({ top: 16 })
}
}
你已經用到了幾個核心屬性:
- 構造:
Polyline({ width, height })或先構造再.width()/.height(); points:折線經過的點;stroke/strokeWidth:線條樣式;strokeLineJoin/strokeLineCap:拐角和兩端的視覺風格。
3. 構造函數 & PolylineOptions
3.1 構造函數簽名
Polyline(options?: PolylineOptions)
options可選;- 內部主要用於指定繪製區域的寬和高;
- 適用於普通頁面、ArkTS 卡片、元服務。
3.2 PolylineOptions(API 18+)
官方把匿名對象規範了一次,現在是個標準對象:
interface PolylineOptions {
width?: Length // ≥ 0,默認 0vp
height?: Length // ≥ 0,默認 0vp
}
要點説明:
-
Length支持:- 數字:
100(vp) - 字符串:
'100' - 資源:
$r('app.string.PolylineWidth')等
- 數字:
- 異常值(
undefined、null、NaN、Infinity)會退回默認值 0; - 如果忘記設寬/高,默認 0×0,什麼都看不到 —— 這是新手常見坑。
4. Polyline 核心屬性詳解
Polyline 支持通用屬性(比如 width / height / offset 等),重點關注的是折線繪製相關屬性。
4.1 points:折線經過的點
.points(value: Array<any>)
- 必填,默認是
[](空數組,不畫任何東西); - 傳入二維數組,每個子數組表示
[x, y],單位是 vp; - 座標基於當前 Polyline 的寬高區域。
例子:
Polyline({ width: 120, height: 80 })
.points([[0, 0], [30, 40], [80, 10], [120, 70]])
注意:
- Polyline 不會自動閉合路徑——它只畫「從第一個點到最後一個點」的折線;
- 如果你希望形成“封閉形狀”,可以手動把首尾座標設成一樣,但那時更適合用
Polygon。
4.2 fill / fillOpacity:填充區域(理論上)
.fill(value: ResourceColor)
.fillOpacity(value: number | string | Resource)
雖然 Polyline 是折線組件,但也支持 fill / fillOpacity:
fill:填充顏色,默認Color.Black;fillOpacity:填充透明度,默認 1.0。
數值規則(和其他圖形組件一致):
- 範圍 [0.0, 1.0];
<0會被夾到 0;>1會被夾到 1;NaN用 0.0;undefined/null/Infinity用 1.0。
實戰經驗:
大多數時候你是把 Polyline 當成「線條」用,會設fillOpacity(0)或壓根不管填充;
如果你把折線首尾連成封閉區域,fill才真正有意義——這時可考慮直接改成Polygon,語義更清晰。
4.3 stroke / strokeWidth / strokeOpacity:線條樣式
.stroke(value: ResourceColor)
.strokeWidth(value: Length)
.strokeOpacity(value: number | string | Resource)
-
stroke:線條顏色;- 不設置時,默認透明度為 0,相當於“沒有線”;
strokeWidth:線寬,默認1vp;strokeOpacity:線條透明度,默認繼承stroke的透明度。
strokeWidth 要點:
- 取值 ≥ 0;
- 異常值(
undefined/null/NaN)使用默認值 1; Infinity按 0 處理(等效看不到線)。
strokeOpacity:
- 範圍 [0.0, 1.0];
- 超出範圍會被鉗制到 0 或 1;
NaN→ 0.0;undefined/null/Infinity→ 1.0。
4.4 虛線:strokeDashArray / strokeDashOffset
.strokeDashArray(value: Array<any>)
.strokeDashOffset(value: number | string)
strokeDashArray:描述虛線的「線段長度 / 間隔長度」週期;strokeDashOffset:指定從哪裏開始繪製這條虛線。
規則總結:
- 默認
[]:實線; - 數組元素單位為 vp,要求 ≥ 0;
-
偶數長度數組(例如
[a, b, c, d]):- 按順序循環:線段 a → 間隙 b → 線段 c → 間隙 d → 線段 a → …;
-
奇數長度數組(例如
[a, b, c]):- 會被當成
[a, b, c, a, b, c],然後按上面的偶數規則使用。
- 會被當成
strokeDashOffset:
- 默認 0;
- 單位 vp;
- 如果傳入
NaN或Infinity,會導致strokeDashArray失效(退變回實線)。
小技巧:
做“流動光線”效果時,可以按照時間週期不斷改變strokeDashOffset的值,讓虛線看起來像在移動。
4.5 拐角 & 端點樣式:strokeLineJoin / strokeLineCap
.strokeLineJoin(value: LineJoinStyle)
.strokeLineCap(value: LineCapStyle)
-
strokeLineJoin控制折線在轉折處的連接方式:- 常見枚舉:
Miter(尖角)、Round(圓角)、Bevel(斜切角); - 默認:
LineJoinStyle.Miter。
- 常見枚舉:
-
strokeLineCap控制折線末端的樣子:- 常見枚舉:
Butt(平頭)、Round(圓頭)、Square(方頭); - 默認:
LineCapStyle.Butt。
- 常見枚舉:
常見組合:
- 想要圓潤一點:
strokeLineJoin(LineJoinStyle.Round).strokeLineCap(LineCapStyle.Round); - UI 比較硬朗:保持默認
Miter + Butt即可。
4.6 strokeMiterLimit:尖角的“尖鋭程度”
.strokeMiterLimit(value: number | string)
這個屬性只有當 strokeLineJoin = LineJoinStyle.Miter 時才生效,用來控制:
外側尖角的長度 與 線寬 的最大比值。
- 默認:4;
-
合法值建議 ≥ 1.0:
[0,1)會按 1.0 處理;- 其他異常值按默認 4 來處理;
Infinity會直接讓stroke失效。
如果折線存在非常尖鋭的角,而 strokeWidth 又比較大,Miter + 大 strokeMiterLimit 會產生非常長的尖刺 —— 這時候可以:
- 降低
strokeMiterLimit; - 或者改用
LineJoinStyle.Round/Bevel。
4.7 antiAlias:抗鋸齒開關
.antiAlias(value: boolean)
- 默認:
true; - 作用:控制邊緣是否做抗鋸齒處理;
- 通常 UI 場景下保持開啓,線條更柔和。
只有在極致追求性能、線條尺寸較大且對美觀不敏感時,才可能考慮關掉。
5. 實戰示例:把 Polyline 用到實際界面
5.1 迷你折線圖(趨勢展示)
用 Polyline 做一個簡單的“本週訪問量折線圖”。
@Entry
@Component
struct MiniChartExample {
private points: number[] = [10, 40, 30, 60, 50, 80, 70]
build() {
Column({ space: 8 }) {
Text('本週訪問趨勢')
.fontSize(16)
.fontWeight(FontWeight.Medium)
// 簡陋版座標映射:假設高度 100,最大值 100
Polyline({ width: 200, height: 100 })
.points(this.toPolylinePoints(this.points))
.fillOpacity(0) // 不填充
.stroke('#FF2787D9')
.strokeWidth(3)
.strokeLineJoin(LineJoinStyle.Round)
.strokeLineCap(LineCapStyle.Round)
Text('數據僅供示意,實際繪製可結合座標軸、網格等組件。')
.fontSize(12)
.fontColor('#99000000')
}
.padding(16)
}
private toPolylinePoints(values: number[]): number[][] {
if (values.length === 0) {
return []
}
const width = 200
const height = 100
const step = width / (values.length - 1)
const max = 100 // 簡化處理,假設最大值 100
return values.map((v, index) => {
const x = step * index
const ratio = Math.min(Math.max(v / max, 0), 1)
const y = height - ratio * height // 越大越靠上
return [x, y]
})
}
}
這裏演示了兩件事:
- 如何將業務數據(數值數組)映射到 Polyline 的座標;
- 如何用
strokeLineJoin/strokeLineCap做一條“圓潤的趨勢線”。
5.2 繪製路徑引導線(配合圖標)
比如在一個「設備連接」頁面畫一條連接兩端設備的線:
@Entry
@Component
struct ConnectLineExample {
build() {
Row()
.width('100%')
.height(120)
.backgroundColor('#FFF5F7FA')
.alignItems(VerticalAlign.Center)
.justifyContent(FlexAlign.Center) {
// 左側設備圖標
Column() {
Image($r('app.media.device_left'))
.width(40)
.height(40)
Text('設備 A').fontSize(12)
}
.margin({ right: 8 })
// 中間折線路徑
Polyline({ width: 160, height: 40 })
.points([[0, 20], [40, 0], [120, 40], [160, 20]])
.fillOpacity(0)
.stroke('#FF64BB5C')
.strokeWidth(4)
.strokeLineJoin(LineJoinStyle.Round)
.strokeLineCap(LineCapStyle.Round)
// 右側設備圖標
Column() {
Image($r('app.media.device_right'))
.width(40)
.height(40)
Text('設備 B').fontSize(12)
}
.margin({ left: 8 })
}
}
}
這是典型的「Polyline 做連線 + 兩邊放組件」的佈局方式,適合用在流程、拓撲、引導類 UI 中。
5.3 attributeModifier:統一管理線條風格
當你有很多 Polyline 樣式是一致的,可以用 AttributeModifier 把線條風格收口。
// 統一定義一套“高亮軌跡”的樣式
class HighlightPolylineModifier implements AttributeModifier<PolylineAttribute> {
applyNormalAttribute(instance: PolylineAttribute): void {
instance.fill('#707070') // 背景填充色(如果需要)
instance.fillOpacity(0.4)
instance.stroke('#FF2787D9') // 高亮線條色
instance.strokeDashArray([16]) // 簡單虛線:線段 16,間隔 16
instance.strokeDashOffset('8')
instance.strokeLineCap(LineCapStyle.Round)
instance.strokeLineJoin(LineJoinStyle.Round)
instance.strokeMiterLimit(5)
instance.strokeOpacity(0.9)
instance.strokeWidth(6)
instance.antiAlias(true)
}
}
@Entry
@Component
struct PolylineModifierExample {
@State modifier: HighlightPolylineModifier = new HighlightPolylineModifier()
build() {
Column({ space: 12 }) {
Text('統一樣式的高亮折線')
.fontSize(16)
.fontWeight(FontWeight.Medium)
Polyline()
.width(200)
.height(80)
.points([[0, 40], [60, 10], [140, 70], [200, 30]])
.attributeModifier(this.modifier)
}
.padding(16)
}
}
好處:
- 樣式集中管理,主題切換/重塑風格只改一處;
- 組件樹更乾淨,Polyline 上不會掛一長串鏈式樣式調用。
5.4 寬高的三種寫法對比
@Entry
@Component
struct PolylineLengthTypeExample {
build() {
Column({ space: 10 }) {
// string 類型
Polyline({ width: '100', height: '100' })
.points([[0, 0], [20, 60], [100, 100]])
.fillOpacity(0)
.stroke(Color.Blue)
.strokeWidth(3)
// number 類型
Polyline({ width: 100, height: 100 })
.points([[0, 0], [20, 60], [100, 100]])
.fillOpacity(0)
.stroke('#FFE84026')
.strokeWidth(3)
// Resource 類型(需在資源中定義字符串)
Polyline({
width: $r('app.string.PolylineWidth'),
height: $r('app.string.PolylineHeight')
})
.points([[0, 0], [20, 60], [100, 100]])
.fillOpacity(0)
.stroke(Color.Green)
.strokeWidth(3)
}
.width('100%')
.padding(16)
}
}
如果你團隊習慣把尺寸參數都抽成資源,這種用法會更統一。
6. 常見坑與排查思路
-
什麼都沒畫出來?
- 首先看
width/height是否為 0(默認就是 0); - 再看
points是否為空數組; - 最後確認
stroke是否設置了,默認是“有顏色但透明度為 0”的效果。
- 首先看
-
虛線效果失效?
- 檢查
strokeDashArray是否為空; - 確認沒有傳
NaN/Infinity給strokeDashOffset,否則虛線配置會失效。
- 檢查
-
線條看起來太“硬”、拐角刺眼?
- 考慮換成
strokeLineJoin(LineJoinStyle.Round); - 或者減小
strokeWidth,降低視覺衝擊。
- 考慮換成
-
某些折線角度下出現很長的尖角?
- 典型是
LineJoinStyle.Miter+ 大線寬; - 可以調小
strokeMiterLimit或改用Round/Bevel。
- 典型是
-
邊緣有明顯鋸齒?
- 確認是否誤關了
.antiAlias(false); - 大多 UI 場景建議一直開啓抗鋸齒。
- 確認是否誤關了