#java #android #многопоточность #canvas #анимация
Здравствуйте, стоит задача, на языке Java под ОС Android нужно написать задачу: создать снеговика и сделать так, чтобы его составляющие объекты меняли цвет с разной скоростью. Смена цветов должна быть реализована в потоке. У меня получилось написать код, но не понимаю, как именно эта анимация должна в этот поток помещаться. Вот собственно полный код, написан в 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() { } } } } Чем заполнять метод run() понимаю, но ругается либо на canvas, p1, или invalidate(). Прошу помощи
Ответы
Ответ 1
Ваш код принципиально неверен. В методе onDraw() нельзя вызывать sleep() и invalidate(). Это все вместе с изменением переменных argb должно происходить в отдельном потоке, а метод onDraw() только отрисовывать экран в соответствии с их состоянием. @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); } Перенести в конструктор и сделать переменной класса: p = new Paint(); p.setStyle(Style.FILL); В run() меняйте rX, gX, bX как вам надо и вызывайте синхронно с основным потоком invalidate() когда надо перерисовать.Ответ 2
Выполнил вот таким образом, может кому-то поможет. Думаю, этот код можно написать гораздо лучше. Поэтому кто сможет, укажите на ошибки, буду благодарен. 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(); // перерисовка объектов } } }
Комментариев нет:
Отправить комментарий