Нарисуйте на холсте с задержкой – «сделайте onDraw () медленнее»

Я использую функции для canvas как drawCircle и drawPoint в android. Это прекрасно работает.

Но теперь проблема состоит в том, чтобы нарисовать эти разные элементы с задержкой, поэтому она выглядит как анимация.

Какой механизм я должен использовать? Попробовали с async, но мне не нравится этот способ сделать это.

Должен ли я использовать какой-то таймер, который просто рисует с интервалом или есть другие умные способы сделать это?

Я использую эту стратегию, сначала объявляю Handler и Runnable таким образом:

private final Observable mObservable = new Observable(); private final static int TIME_STEP_MS = 5; private final Handler mHandler = new Handler(); private final Runnable mTimeManager = new Runnable() { public void run() { mObservable.notifyObservers(TIME_STEP_MS); mHandler.postDelayed(mTimeManager, TIME_STEP_MS); } }; 

Затем, когда я хочу запустить мой менеджер времени, я просто вызываю mTimeManager.run (), и он начнет периодически уведомлять мой Observer (ранее добавленный).

Если вам почему-то нужно остановить таймер или что-то, что вы просто делаете:

  mHandler.removeCallbacks(mTimeManager); 

[EDIT – более полный код]

Хорошо, давайте сделаем это более ясным, сначала я создал специальный объект Observable, подобный этому [это необязательно]:

  private final Observable mObservable = new Observable() { public void notifyObservers() { setChanged(); super.notifyObservers(); }; @Override public void notifyObservers(Object data) { setChanged(); super.notifyObservers(data); }; }; 

Причина в том, что я не могу вызвать setChanged () вне класса Observable – он защищен, если он не изменен, он не уведомляет обозревателя.

Другие объявления сохраняют то же самое, что показано выше, теперь мне нужно запустить этот TimeManager где-то, мое приложение – LiveWallpaper, и я делаю все материалы для рендеринга в класс, который расширяет Thread но вам это не нужно, я сделал метод resumeDrawing() , оно вызывается сразу после super.start(); В моем @Override public synchronized void start() из класса Thread , метод выглядит следующим образом:

  public void resumeDrawing() { if (!mTimeManagerRunning) // just a boolean field in my class { System.err.println("Resuming renderer."); // just for debug mTimeManager.run(); mTimeManagerRunning = true; } else { System.err.println("Renderer already running."); // just for debug } } 

И он двойственный:

  public void pauseDrawing() { if (mTimeManagerRunning) { System.err.println("Pausing renderer."); mHandler.removeCallbacks(mTimeManager); mTimeManagerRunning = false; } else { System.err.println("Renderer already paused."); } } 

Хорошо, теперь мы можем начать и остановить диспетчера времени, но кто слушает? Никто! Поэтому давайте добавим: В конструкторе моего Renderer я добавляю некоторые Observer в мой объект mObservable , один из них – сам Renderer, поэтому мой рендеринг расширяет Thread и реализует Observer :

  @Override // from Observer interface public void update(Observable arg0, Object arg1) { mElapsedMsRedraw += (Integer) arg1; if (mElapsedMsRedraw >= mDrawingMsPerFrame) { mElapsedMsRedraw = 0; drawEm(); // refresh the canvas and stuff } } 

Для добавления наблюдателей вы просто делаете mObservable.addObserver(THE_OBJECT - Implements Observer)

Вы можете видеть, что я не повторно обрабатываю свой материал каждый раз, когда меня уведомляют, потому что я использую этот TimeManager для других, а не просто обновляет Canvas как обновление позиции объектов, которые я хочу рисовать только внутренне.

Итак, что нужно для замедления чертежа, – это изменить способ изменения внутренних объектов во время прохода, я имею в виду ваши круги и точки и т. Д., Или вы можете сделать свой шаг по времени, я рекомендую первый.

Было ли это яснее? Я надеюсь, что это помогает.

Я бы использовал таймер или создавал анимацию. Вы можете создавать анимации, которые будут делать всевозможные вещи, включая изменение прозрачности с течением времени.

Вот Android-документация для анимационных ресурсов

Я считаю, что могут быть сложные способы сделать это, но для моих нужд я использовал простой метод, который имеет много преимуществ: я сначала создаю записи координат (и любых других данных) для каждой точки чертежа – вместо Нарисовать точки на месте – и затем воспроизвести их с помощью таймера (Android-обработчик, желательно). Это также дает множество возможностей при фактическом рисовании: пауза, скорость / медленнее, назад, … Я не знаю, можно ли использовать этот метод для сложных рисунков, но это прекрасно для рисования фигур, кривых, поверхностей , и т.д.