Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

203
Views
¿Cómo puedo hacer una animación de dibujo con un hijo de View, dibujando cada línea de Path una por una?

Usando el código que encontré en esta respuesta de StackOverflow , puedo dibujar con éxito cualquier cosa en un lienzo con el dedo, y veré lo que dibujo mientras lo dibujo. A partir de esto, quiero hacer que una función se active al presionar un botón que hará dos cosas:

  1. Borra lo que está dibujado sobre el lienzo.
  2. Vuelva a reproducir la imagen que se dibujó sobre él antes de limpiar el lienzo, volviendo a dibujar las líneas de cada ruta una por una a una velocidad constante.

Para hacerlo, he modificado ligeramente el código de onTouchEvent , por lo que almacena cada punto dibujado en consecuencia:

 @Override public boolean onTouchEvent(MotionEvent event) { StrokePoint point; switch (event.getAction()){ case MotionEvent.ACTION_DOWN: mPath.moveTo(event.getX(), event.getY()); // Retrieve strokes in memory stroke_buffer = new Stroke(); stroke_buffer.points = new ArrayList<StrokePoint>(); point = new StrokePoint(); point.x = event.getX(); point.y = event.getY(); stroke_buffer.points.add( point ); break; case MotionEvent.ACTION_MOVE: mPath.lineTo(event.getX(), event.getY()); // Retrieve strokes in memory point = new StrokePoint(); point.x = event.getX(); point.y = event.getY(); stroke_buffer.points.add( point ); invalidate(); break; case MotionEvent.ACTION_UP: // Retrieve strokes in memory strokes.add(stroke_buffer); break; default: break; } return true; }

De esa manera, puedo cargar los puntos X e Y más tarde en bucles (al menos esa es la idea). El problema es que no estoy seguro de cómo activar el "redibujar" en el lienzo para cada línea. Traté de almacenar el lienzo de "onDraw" de esta manera:

 @Override protected void onDraw(Canvas canvas) { canvas.drawPath(mPath, mPaint); // For trying to make the "redraw" later this.mCanvas = canvas; super.onDraw(canvas); }

Y luego, hago este método para el botón que quiero borrar y reproducir los trazos dibujados previamente:

 public void replayStrokes() { // I start a new path from scratch ad-hoc the "redraw" animation. mPath = new Path(); Log.i("SANDBOX_INFO", "Button pressed"); // Intention here is leaving the "whiteboard" clear again. mCanvas.drawRGB(255, 255, 255); invalidate(); this.draw(mCanvas); SystemClock.sleep(1000); // Redraw "line by line" loop mPath.moveTo(strokes.get(0).points.get(0).x, strokes.get(0).points.get(0).y); for (int i = 0; i < strokes.size(); i++) { for (int j = 0; j < strokes.get(i).points.size(); j++) { if (i == 0 && j == 0) continue; mPath.lineTo(strokes.get(i).points.get(j).x, strokes.get(i).points.get(j).y); mCanvas.drawPath(mPath, mPaint); invalidate(); this.draw(mCanvas); SystemClock.sleep(100); } } }

Cuando presiono el botón, el método replayStrokes no se comporta como se esperaba. Es como si se quedara "pensando" (procesando) y, cuando menos te lo esperas, refresca todos los cambios de un solo golpe; en cambio, quiero que sea una animación fluida en la que puedas ver todo el Camino previamente dibujado con el dedo, reproducido línea por línea, punto por punto. ¿Qué estoy haciendo mal? ¿Qué debo cambiar para obtener el comportamiento esperado?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Terminé encontrando una solución gracias al comentario de @VitorHugoSchwaab. Pequeño recordatorio: se supone que todo el código que publiqué en esta pregunta está dentro de una public class DrawCanvas extends View . Eso dijo:

Entonces, dejé el "método de activación" así:

 private int s, p; private boolean replay_mode; public void replayStrokes() { s = 0; p = 0; replay_mode = true; invalidate(); }

Y modifiqué el método onDraw así (lo transformé en un Megamoth , pero eso lo puedo arreglar más tarde: P):

 @Override protected void onDraw(Canvas canvas) { if (replay_mode) { if (s == 0 && p == 0) { Log.i("SANDBOX_INFO", "Replay Mode START"); canvas.drawRGB(255, 255, 255); p++; replayPath.reset(); replayPath.moveTo(strokes.get(0).points.get(0).x, strokes.get(0).points.get(0).y); invalidate(); } else { Log.i("SANDBOX_INFO", "Replaying --> S:" + s + " P:" + p); if (p == 0) { replayPath.moveTo(strokes.get(s).points.get(p).x, strokes.get(s).points.get(p).y); } else { replayPath.lineTo(strokes.get(s).points.get(p).x, strokes.get(s).points.get(p).y); canvas.drawPath(replayPath, mPaint); } int points_size = strokes.get(s).points.size(); if (s == strokes.size() - 1 && p == points_size - 1) { Log.i("SANDBOX_INFO", "Replay Mode END"); replay_mode = false; } else if (p == points_size - 1) { s++; p = 0; } else { p++; } } invalidate(); } else { canvas.drawPath(mPath, mPaint); } super.onDraw(canvas); }

Esto funciona. Sin embargo, hay un efecto de falla de "parpadeo" mientras se repiten los trazos. Creo que eso podría deberse a que en realidad está "redibujando" toda la "ruta de reproducción" en cada cuadro. Basado en esta suposición, intentaré solucionar el problema cuando tenga más tiempo para codificar.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!