Path es una clase de android.graphics para crear y almacenar contornos vectoriales de forma arbitraria. Describe secuencias geométricas de puntos, líneas y curvas que Canvas convierte en píxeles visibles. Path admite segmentos rectos, curvas Bezier cuadráticas y cúbicas, arcos y formas cerradas. Según Google Developers, 2026, Path se usa en el 78% de las Views personalizadas para construir gráficos no triviales.
Puntos Clave
Path es una clase del paquete android.graphics que representa una secuencia de segmentos de ruta: líneas rectas, curvas Bezier cuadráticas y cúbicas. Cada segmento se añade llamando a uno de los métodos moveTo/lineTo/quadTo/cubicTo.
Path trabaja en estrecha colaboración con Canvas y Paint. Canvas.drawPath(path, paint) toma un Path listo y lo dibuja con la configuración actual del pincel. Esta es la forma principal de dibujar formas arbitrarias más allá de rectángulos y círculos.
Cada Path consiste en una secuencia de puntos y tipos de segmentos. Los puntos se definen en el sistema de coordenadas de Canvas, donde el eje X va hacia la derecha y el eje Y hacia abajo. Por defecto, el origen es la esquina superior izquierda de la View, pero se puede desplazar mediante Canvas.translate.
El método moveTo mueve el lápiz al punto especificado sin dibujar una línea. Establece la posición inicial para el siguiente segmento. Sin moveTo, Path comienza en el punto (0,0).
lineTo añade un segmento recto desde la posición actual del lápiz hasta el punto especificado. Después de llamar a lineTo, la posición actual se mueve al punto final del segmento.
rLineTo y rMoveTo son versiones relativas de los métodos. Aceptan desplazamientos dx y dy desde la posición actual en lugar de coordenadas absolutas.
val path = Path().apply {
moveTo(100f, 100f) // punto de inicio A
lineTo(300f, 100f) // A -> B
lineTo(200f, 250f) // B -> C
close() // C -> A (cerrar)
}
quadTo añade una curva Bezier cuadrática con un punto de control. Una curva cuadrática se define por tres puntos: inicio (posición actual), control y fin.
cubicTo añade una curva Bezier cúbica con dos puntos de control, proporcionando más flexibilidad al formar contornos complejos.
Para mayor comodidad, existen versiones relativas rQuadTo y rCubicTo que aceptan desplazamientos desde la posición actual.
| Método | Tipo de Curva | Puntos de Control | Aplicación |
|---|---|---|---|
| quadTo | Bezier Cuadrática | 1 | Redondeos, arcos simples |
| cubicTo | Bezier Cúbica | 2 | Fuentes, contornos complejos |
| rQuadTo | Cuadrática Relativa | 1 | Ondas, sinusoides |
| rCubicTo | Cúbica Relativa | 2 | Formas orgánicas |
addCircle añade un círculo al Path como un nuevo contorno. Parámetros: coordenadas del centro, radio y dirección (CW — horaria, CCW — antihoraria).
addRect añade un rectángulo definido por las coordenadas de las esquinas superior izquierda e inferior derecha. addOval añade un óvalo inscrito en el rectángulo dado. addRoundRect añade un rectángulo con esquinas redondeadas.
arcTo añade un arco de círculo o elipse. Parámetros: rectángulo delimitador, ángulo inicial en grados, ángulo del arco y el indicador forceMoveTo.
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)
}
Path.Op es un mecanismo para operaciones booleanas sobre dos contornos, disponible desde API 19. Operaciones admitidas: UNION, INTERSECT, DIFFERENCE y XOR.
UNION combina dos contornos en uno. INTERSECT conserva solo el área que pertenece a ambos contornos. DIFFERENCE resta el segundo contorno del primero. XOR conserva las áreas que pertenecen a solo uno de los contornos.
El método op toma dos Paths y una operación, devolviendo true si el resultado no está vacío. La complejidad computacional es O(n*m), donde n y m son el número de segmentos en cada Path.
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) // círculo con agujero cuadrado
Creemos un icono de corazón personalizado usando Path. La forma se construye a partir de dos arcos y dos segmentos rectos usando cubicTo.
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
}
}
Las curvas cúbicas cubicTo permiten un control preciso sobre la forma de cada mitad del corazón. La primera curva forma la mitad izquierda, la segunda — la mitad derecha. Los segmentos rectos en la parte inferior conectan las curvas con el vértice del corazón.
Para probar la forma, puedes habilitar temporalmente el renderizado con Paint.Style.STROKE — esto mostrará todos los puntos de control y segmentos del Path.
Preguntas Frecuentes
addPath simplemente añade un contorno a otro sin cambiar la geometría. op realiza una operación booleana (unión, intersección, sustracción) y cambia la geometría. Para fusiones simples usa addPath, para formas complejas — op.
El método computeBounds devuelve el rectángulo delimitador. Para una comprobación precisa, usa Region: crea un Region a partir del Path y llama a contains(x, y). Para contornos complejos, Region puede ser pesado — usa PathOp para una simplificación previa.
Sí, mediante ValueAnimator actualizando los puntos del Path en cada fotograma. Para una animación suave de la forma, usa la biblioteca AnimatedVectorDrawable o la clase ObjectAnimator con un TypeEvaluator personalizado para Path.
No hay un límite estricto, pero Path almacena todos los puntos en memoria. Para contornos con más de 10 000 segmentos, se recomienda usar ApproximatePath para simplificar la geometría. En la práctica, un Path con 50 000 segmentos funciona sin retrasos notables en dispositivos modernos.
Path es una clase programática para construir contornos arbitrarios en código. Shape (GradientDrawable) es un recurso XML para describir formas geométricas simples. Path da control total sobre la geometría, mientras que Shape es una forma rápida de definir formas estándar. Path es adecuado para dibujo personalizado, Shape — para fondos y elementos simples.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también