En Android, ¿cómo hago extrañas áreas de recorte?

Aquí es cómo crear un área de recorte la forma de un círculo:

Path path = new Path(); path.addCircle(200,200,100,Direction.CW); c.clipPath(path); // c is a Canvas 

Ahora hay un área de recorte en el lienzo que impide dibujar algo fuera de los límites de ese círculo. Pero, ¿qué pasa si quiero tener el área de recorte en forma de donut (o lo que sea)?

Intenté jugar alrededor con crear una segunda trayectoria y usar toggleInverseFillType en él y después agregar eso a la trayectoria original, pero eso no parece trabajar.

Alternativamente, en vez de usar un Path, ¿es posible crear un Bitmap para usar como una máscara y configurarlo como una máscara de recorte en el Canvas de alguna manera?

EDIT: La respuesta es exactamente lo que necesitaba con una pequeña adición. Cuando realice varias operaciones en un lienzo, utilice siempre Op.REPLACE en la primera llamada a clipPath. Esto reemplazará cualquier clipPath existente en ese lienzo.

Para referencia, aquí es lo que descubrí lo que significan los 6 valores Region.Op diferentes. Imagine un diagrama de venn con 2 círculos. "B" es la parte donde los 2 círculos se superponen. "A" es el círculo izquierdo que no se superpone. "C" es el círculo derecho que no se superpone.

 c.clipPath(a,Region.Op.REPLACE); c.clipPath(b,???); Region.Op.DIFFERENCE -> A.. Region.Op.INTERSECT -> .B. Region.Op.REPLACE -> .BC Region.Op.REVERSE_DIFFERENCE -> ..C Region.Op.UNION -> ABC Region.Op.XOR -> AC 

Los "." Indica la parte que no está dibujada. Lo siento si eso no es particularmente claro. Es difícil describir bien sin gráficos.

De la Canvas javadoc :

Canvas#clipPath(Path path, Region.Op op) – Modifica el clip actual con la ruta especificada.

Por lo tanto, para su ejemplo donut:

  1. Crear 2 rutas. Uno para el círculo más grande, uno para el círculo más pequeño.
  2. Canvas#clipPath( Path ) con mayor Path círculo.
  3. Llame al Canvas#clipPath( Path, Region.Op ) en su lienzo con el círculo más pequeño Path para el primer argumento y el valor de enum Region.Op apropiado para el segundo argumento.

     Path largePath = new Path(); largePath.addCircle(200,200,100,Direction.CW); Path smallPath = new Path(); smallPath.addCircle(200,200,40,Direction.CW); c.clipPath(largePath); // c is a Canvas c.clipPath(smallPath, Region.Op.DIFFERENCE); 

Una vez más, modifique el valor de enum Region.Op para obtener diferentes efectos …

  • ¿Es posible inyectar código en una aplicación Android?
  • ¿Cómo diferencia exactamente JVM de Dalvik y / o ART?
  • ¿Cómo puedo detectar el tiempo de ejecución de Android (Dalvik o ART)?
  • ¿Por qué Android necesita una máquina virtual (DVM)?
  • 64 bits android, aplicación de 32 bits con 32 bits de biblioteca nativa
  • LinearAlloc excedió la capacidad (5242880), ultimo = 1092 Error al instalar en mi dispositivo Tablet Samsung
  • Lenguaje de programación personalizado (jar) en Android
  • Mockito en el emulador de Android
  • ¿Cuál es la mejor manera de aprender Smali (y cómo / cuándo usar los opcodes de Dalvik VM)?
  • "Tiros" y "anotación para excepción" en el bytecode de Dalvik
  • Impacto de 'instanceof' en el código Java de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.