Hello, there is a task; in Java, under Android, you need to write a task: create a snowman and make its constituent objects change color at different speeds. Color change should be implemented in the stream.
I managed to write code, but I don’t understand how exactly this animation should fit into this stream. Here is the actual code, written in Eclipse:

package ru.ucheba; import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Style; import android.os.Bundle; import android.os.SystemClock; import android.view.View; public class Zadanie2 extends Activity { int a = 255; int r = 100; int g = 0; int b = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new Panel(this)); } class Panel extends View { public Panel(Context context) { super(context); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); Paint p1 = new Paint(); p1.setStyle(Style.FILL); p1.setARGB(a, r, g, b); canvas.drawCircle(270, 170, 70, p1); for (int i = 0; i < 5; i++) { r--; SystemClock.sleep(10); invalidate(); } for (int j = 0; j < 15; j++) { p1.setARGB(a, r, g, b); g--; canvas.drawCircle(270, 310, 100, p1); SystemClock.sleep(20); invalidate(); } for (int k = 0; k < 30; k++) { p1.setARGB(a, r, g, b); b--; canvas.drawCircle(270, 510, 150, p1); SystemClock.sleep(40); invalidate(); } } class Task extends Thread { @Override public void run() { } } } } 

Than to fill the run() method I understand, but I swear on either canvas , p1 , or invalidate() . I ask for help

  • The word "swears" can be applied to a grumpy wife. Programmers have specific errors, the solution of which is based precisely on their accuracy (what the error is), and not on abstract statements about unspecified "curses." While you can only advise - in response to curses, say a few kind words, it will help smooth out the conflict or also curse in response, it will help relieve the tension ... - pavlofff
  • For p1 and canvas , you obviously have a limited scope for variables. It is worth getting acquainted with the transfer of values ​​to the nested class in general and the new stream in particular. - pavlofff
  • Consider the spacing between animation frames. 10 ms is 100 fps, not every device will pull it :) - Eugene Krivenja

2 answers 2

Your code is fundamentally wrong. In the onDraw() method, onDraw() cannot call sleep() and invalidate() . This all together with the change of argb variables should occur in a separate thread, and the onDraw() method only draws the screen according to their state.

  @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); p.setARGB(a, r1, g1, b1); canvas.drawCircle(270, 170, 70, p); p.setARGB(a, r2, g2, b2); canvas.drawCircle(270, 310, 100, p); p.setARGB(a, r3, g3, b3); canvas.drawCircle(270, 510, 150, p); } 

Transfer to the constructor and make the class variable:

 p = new Paint(); p.setStyle(Style.FILL); 

In run() change rX, gX, bX as you need and call synchronously with the main thread invalidate() when you need to redraw.

    Fulfilled in this way, can someone help. I think this code can be written much better. Therefore, who can, point out the errors, I will be grateful.

     import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.view.View; public class Zadanie2 extends Activity { int[] Colo = { 10, 20, 30 }; // массив со значСниями исп. для Ρ†Π²Π΅Ρ‚ΠΎΠ² // снСговика public Thread myThread1, myThread2, myThread3; // созданиС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… для ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new Panel(this)); // использованиС класса Panel Π² качСствС Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ‚ΠΈ myThread1 = new Thread(new Runnable() { @Override public void run() { int znak = 1; while (true) { if ((znak > 0) && (Colo[0] > 250)) { znak = -znak; } if ((znak < 0) && (Colo[0] < 5)) { znak = -znak; } Colo[0] += znak; try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } } }); myThread2 = new Thread(new Runnable() { @Override public void run() { int znak2 = 1; while (true) { if ((znak2 > 0) && (Colo[1] > 250)) { znak2 = -znak2; } if ((znak2 < 0) && (Colo[1] < 5)) { znak2 = -znak2; } Colo[1] += znak2; try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } } }); myThread3 = new Thread(new Runnable() { @Override public void run() { int znak3 = 1; while (true) { if ((znak3 > 0) && (Colo[2] > 250)) { znak3 = -znak3; } if ((znak3 < 0) && (Colo[2] < 5)) { znak3 = -znak3; } Colo[2] += znak3; try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); } } } }); // запуск ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² myThread1.start(); myThread2.start(); myThread3.start(); } class Panel extends View { public Panel(Context context) { super(context); } @Override public void onDraw(Canvas canvas) { super.onDraw(canvas); float w, h, cx, cy, radius; // ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, для Π°Π΄Π°ΠΏΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ располоТСния снСговика w = getWidth(); // считываСт ΡˆΠΈΡ€ΠΈΠ½Ρƒ h = getHeight(); // считываСт высоту cx = w / 2; cy = h / 2; // для ΠΎΡ€ΠΈΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ экрана if (w > h) { radius = h / 8; } else { radius = w / 8; } Paint p1 = new Paint(); p1.setStyle(Paint.Style.FILL); p1.setColor(Color.rgb(Colo[0], 255, 255)); canvas.drawCircle(cx, cy - h / 3, radius, p1); Paint p2 = new Paint(); p2.setStyle(Paint.Style.FILL); p2.setColor(Color.rgb(255, Colo[1] * 2, 255)); canvas.drawCircle(cx, cy - h / 3 + radius * 2, (float) (radius * 1.5), p2); Paint p3 = new Paint(); p3.setStyle(Paint.Style.FILL); p3.setColor(Color.rgb(255, 255, Colo[2] * 3)); canvas.drawCircle(cx, cy - h / 3 + radius * 5, radius * 2, p3); invalidate(); // пСрСрисовка ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² } } }