Я не пробовал использовать View
для расширения Canvas
, но для своей игры я использую тот же метод, что и в примере игры LunarLander:
public class CustomView extends SurfaceView implements SurfaceHolder.Callback
Полезность этогочто он дает вам дескрипторы для SurfaceHolder (чтобы вы могли вызвать холст, который рисуется на экран), и обратные вызовы для surfaceCreated
, surfaceChanged
и surfaceDestroyed
.Это позволяет вам делать такие вещи, как рисование пользовательской анимации, как только поверхность становится доступной, или следить за тем, чтобы вы не пытались рисовать на холсте после его деактивации.Просмотр LunarLander должен показать вам, как правильно их использовать.
Редактировать: Я вспомнил еще одну причину, почему было полезно использовать SurfaceHolder.Это потому, что, как я упоминал выше, он позволяет вам получить прямой доступ к холсту, который рисуется на экране.С SurfaceHolder это делается не путем переопределения onDraw, а с использованием чего-то вроде Canvas canvas = mSurfaceHolder.lockCanvas()
.(См. LunarLander для точного синтаксиса).Это важно по той причине, что позволяет точно контролировать, когда происходит рисование.Если вы можете работать только путем переопределения onDraw (), тогда рисование не произойдет, пока ваша программа не перейдет в фазу ожидания.Другими словами, вы не можете использовать invalidate()
и onDraw()
в цикле, потому что рисование не произойдет, пока цикл не завершится.А поскольку вы, скорее всего, будете использовать циклы для таких вещей, как рисование фигуры, движущейся по экрану, это становится проблемой.
Примечание. Может быть возможно избежать этой проблемы, используя несколько потоков.Я просто не пробовал этого, так как это не требуется для моей игры;единственная анимация - это анимации фиксированной длины в ответ на пользовательский ввод, а не что-то непрерывно движущееся в фоновом режиме, поэтому я еще не экспериментировал с несколькими потоками.