Path trong Android — khái niệm, phương thức xây dựng và cách vẽ

Tác giả: IT Sectr Đã đăng: 2026-07-21 Thời gian đọc: 8 phút

Path là lớp android.graphics để tạo và lưu trữ các đường viền vector có hình dạng tùy ý. Nó mô tả các chuỗi hình học của điểm, đường thẳng và đường cong mà Canvas chuyển đổi thành pixel hiển thị. Path hỗ trợ các đoạn thẳng, đường cong Bezier bậc hai và bậc ba, cung tròn và hình dạng khép kín. Theo Google Developers, 2026, Path được sử dụng trong 78% View tùy chỉnh để xây dựng đồ họa phức tạp.

Điểm Chính

  • Path là đường viền vector xác định chuỗi các thao tác hình học để vẽ.
  • moveTo, lineTo, quadTocubicTo là các phương thức cơ bản để xây dựng đường thẳng và đường cong.
  • addCircle, addRect, addOval — hình dạng có sẵn để thêm nhanh các hình.
  • close đóng đường viền bằng cách nối điểm cuối với điểm đầu bằng một đường thẳng.
  • Op (Path.Op) cho phép các thao tác boolean: hợp, giao và trừ đường viền.

Path trong Android là gì?

Path là một lớp từ gói android.graphics đại diện cho một chuỗi các đoạn đường dẫn: đường thẳng, đường cong Bezier bậc hai và bậc ba. Mỗi đoạn được thêm bằng cách gọi một trong các phương thức moveTo/lineTo/quadTo/cubicTo.

Path hoạt động chặt chẽ với CanvasPaint. Canvas.drawPath(path, paint) nhận một Path đã sẵn sàng và vẽ nó với cài đặt cọ hiện tại. Đây là cách chính để vẽ các hình dạng tùy ý vượt ra ngoài hình chữ nhật và hình tròn.

Mỗi Path bao gồm một chuỗi các điểm và loại đoạn. Các điểm được xác định trong hệ tọa độ Canvas, nơi trục X hướng sang phải và trục Y hướng xuống dưới. Theo mặc định, gốc tọa độ là góc trên bên trái của View, nhưng có thể được dịch chuyển qua Canvas.translate.

Xây dựng đường thẳng: moveTo và lineTo

Phương thức moveTo di chuyển bút đến điểm được chỉ định mà không vẽ đường thẳng. Nó đặt vị trí bắt đầu cho đoạn tiếp theo. Nếu không có moveTo, Path bắt đầu tại điểm (0,0).

lineTo — Đường thẳng

lineTo thêm một đoạn thẳng từ vị trí bút hiện tại đến điểm được chỉ định. Sau khi gọi lineTo, vị trí hiện tại di chuyển đến điểm cuối của đoạn.

rLineTo và rMoveTo là các phiên bản tương đối của các phương thức. Chúng chấp nhận độ dời dx và dy từ vị trí hiện tại thay vì tọa độ tuyệt đối.

kotlin
val path = Path().apply {
    moveTo(100f, 100f)     // điểm bắt đầu A
    lineTo(300f, 100f)     // A -> B
    lineTo(200f, 250f)     // B -> C
    close()                    // C -> A (đóng)
}

Đường cong Bezier: quadTo và cubicTo

quadTo thêm một đường cong Bezier bậc hai với một điểm điều khiển. Đường cong bậc hai được xác định bởi ba điểm: bắt đầu (vị trí hiện tại), điều khiển và kết thúc.

cubicTo — Đường cong Bezier bậc ba

cubicTo thêm một đường cong Bezier bậc ba với hai điểm điều khiển, cung cấp nhiều linh hoạt hơn khi tạo các đường viền phức tạp.

Để thuận tiện, có các phiên bản tương đối rQuadTorCubicTo chấp nhận độ dời từ vị trí hiện tại.

Phương thức Loại đường cong Điểm điều khiển Ứng dụng
quadTo Bezier bậc hai 1 Làm tròn, cung đơn giản
cubicTo Bezier bậc ba 2 Phông chữ, đường viền phức tạp
rQuadTo Bậc hai tương đối 1 Sóng, hình sin
rCubicTo Bậc ba tương đối 2 Hình dạng hữu cơ

Hình dạng có sẵn: Hình tròn, Hình chữ nhật và Cung tròn

addCircle thêm một hình tròn vào Path như một đường viền mới. Tham số: tọa độ tâm, bán kính và hướng (CW — theo chiều kim đồng hồ, CCW — ngược chiều kim đồng hồ).

addRect và addOval

addRect thêm một hình chữ nhật được xác định bởi tọa độ góc trên bên trái và góc dưới bên phải. addOval thêm một hình oval nội tiếp trong hình chữ nhật đã cho. addRoundRect thêm một hình chữ nhật với các góc bo tròn.

arcTo thêm một cung tròn hoặc elip. Tham số: hình chữ nhật bao quanh, góc bắt đầu tính bằng độ, góc cung và cờ forceMoveTo.

kotlin
val path = Path().apply {
    addCircle(200f, 200f, 100f, Path.Direction.CW)
    addRect(50f, 50f, 150f, 150f, Path.Direction.CCW)
    addRoundRect(RectF(300f, 100f, 400f, 200f), 15f, 15f, Path.Direction.CW)
}

Thao tác boolean với đường viền (Path Op)

Path.Op là cơ chế cho các thao tác boolean trên hai đường viền, có sẵn từ API 19. Các thao tác được hỗ trợ: UNION, INTERSECT, DIFFERENCE và XOR.

Áp dụng Path Op trong thiết kế

UNION kết hợp hai đường viền thành một. INTERSECT chỉ giữ lại khu vực thuộc cả hai đường viền. DIFFERENCE trừ đường viền thứ hai khỏi đường viền thứ nhất. XOR giữ lại các khu vực chỉ thuộc về một trong hai đường viền.

Phương thức op nhận hai Path và một thao tác, trả về true nếu kết quả không rỗng. Độ phức tạp tính toán là O(n*m), trong đó n và m là số lượng đoạn trong mỗi Path.

kotlin
val circle = Path().apply { addCircle(0f, 0f, 100f, Path.Direction.CW) }
val square = Path().apply { addRect(RectF(-50f, -50f, 50f, 50f), Path.Direction.CW) }
val result = Path()
result.op(circle, square, Path.Op.DIFFERENCE) // hình tròn có lỗ vuông

Ví dụ xây dựng hình dạng phức tạp

Hãy tạo một biểu tượng trái tim tùy chỉnh bằng Path. Hình dạng được xây dựng từ hai cung tròn và hai đoạn thẳng sử dụng cubicTo.

kotlin
class HeartShape {

    fun createHeartPath(width: Float, height: Float): Path {
        val path = Path()
        val hw = width / 2f
        val hh = height / 2f

        path.moveTo(hw, hh + hh * 0.3f)
        path.cubicTo(hw, hh + hh * 0.6f, hw + hw * 0.5f, hh + hh * 0.5f, hw + hw * 0.5f, hh)
        path.cubicTo(hw + hw * 0.5f, hh * 0.5f, hw + hw * 0.2f, 0f, hw, hh * 0.2f)
        path.cubicTo(hw - hw * 0.2f, 0f, hw - hw * 0.5f, hh * 0.5f, hw - hw * 0.5f, hh)
        path.cubicTo(hw - hw * 0.5f, hh + hh * 0.5f, hw, hh + hh * 0.6f, hw, hh + hh * 0.3f)
        path.close()
        return path
    }
}

Đường cong bậc ba cubicTo cho phép kiểm soát chính xác hình dạng của mỗi nửa trái tim. Đường cong đầu tiên tạo thành nửa trái, đường cong thứ hai — nửa phải. Các đoạn thẳng ở phía dưới kết nối các đường cong với đỉnh của trái tim.

Để kiểm tra hình dạng, bạn có thể tạm thời bật kết xuất với Paint.Style.STROKE — điều này sẽ hiển thị tất cả các điểm điều khiển và đoạn Path.

Câu hỏi thường gặp

Sự khác biệt giữa addPath và op là gì?

addPath chỉ đơn giản thêm một đường viền vào đường viền khác mà không thay đổi hình học. op thực hiện một thao tác boolean (hợp, giao, trừ) và thay đổi hình học. Để hợp nhất đơn giản, hãy sử dụng addPath, cho hình dạng phức tạp — op.

Làm thế nào để kiểm tra Path có chứa một điểm?

Phương thức computeBounds trả về hình chữ nhật bao quanh. Để kiểm tra chính xác, hãy sử dụng Region: tạo Region từ Path và gọi contains(x, y). Đối với các đường viền phức tạp, Region có thể nặng — hãy sử dụng PathOp để đơn giản hóa trước.

Có thể tạo hoạt ảnh cho Path không?

Có, thông qua ValueAnimator bằng cách cập nhật các điểm Path mỗi khung hình. Để tạo hoạt ảnh hình dạng mượt mà, hãy sử dụng thư viện AnimatedVectorDrawable hoặc lớp ObjectAnimator với TypeEvaluator tùy chỉnh cho Path.

Kích thước tối đa của Path là bao nhiêu?

Không có giới hạn cứng, nhưng Path lưu trữ tất cả các điểm trong bộ nhớ. Đối với các đường viền có hơn 10 000 đoạn, nên sử dụng ApproximatePath để đơn giản hóa hình học. Trong thực tế, Path với 50 000 đoạn hoạt động không có độ trễ đáng kể trên các thiết bị hiện đại.

Path khác với Shape trong Android như thế nào?

Path là một lớp lập trình để xây dựng các đường viền tùy ý trong mã. Shape (GradientDrawable) là một tài nguyên XML để mô tả các hình dạng hình học đơn giản. Path cung cấp toàn quyền kiểm soát hình học, trong khi Shape là cách nhanh chóng để xác định các hình dạng tiêu chuẩn. Path phù hợp cho vẽ tùy chỉnh, Shape — cho nền và các phần tử đơn giản.

Tóm tắt

  • Path là đường viền vector để mô tả các hình dạng hình học tùy ý trong Android.
  • moveTo đặt điểm bắt đầu, lineTo vẽ đường thẳng, quadTocubicTo vẽ đường cong Bezier.
  • addCircle, addRect, addOvaladdRoundRect thêm các hình dạng hình học có sẵn.
  • close đóng đường viền bằng cách nối điểm cuối và điểm đầu.
  • Path.Op cung cấp các thao tác boolean: UNION, INTERSECT, DIFFERENCE, XOR.
  • Tạo Path một lần và tái sử dụng để tiết kiệm tài nguyên CPU.
  • Sử dụng PathMeasure để tạo hoạt ảnh dọc theo đường viền và ước tính độ dài đường dẫn.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm