Viewに描画ができるようになったので、今度は自前でアニメーションをさせてみる。
アニメーションをするには、一定時間ごとに図形の状態を更新させ、再描画するというのが基本的な考え方である。
そこで、以下のように簡単なアニメーションを行うカスタムViewを書いてみた。
MyView.java
public class MyView extends View { private int x = 0; private ScheduledExecutorService ses = null; private final Runnable task = new Runnable(){ @Override public void run() { // 移動処理 x += 2; // 画面を更新する postInvalidate(); } }; /** * コンストラクタ * @param context */ public MyView(Context context) { super(context); } // 描画処理 @Override protected void onDraw(Canvas canvas) { final Paint paint = new Paint(); paint.setColor(Color.CYAN); canvas.drawRect(x, 20.f, x + 40f, 60.f, paint); } public void onResume(){ // タイマーを作成する ses = Executors.newSingleThreadScheduledExecutor(); // 100msごとにRunnableの処理を実行する ses.scheduleAtFixedRate(task, 0L, 100L, TimeUnit.MILLISECONDS); } public void onPause(){ // タイマーを停止する ses.shutdown(); ses = null; } }
このコードでは、100msごとに図形のx座標を+2ずつ加算して再描画している。結果、図形が右へ移動しているように見えている。
繰り返しのタイマーのような処理をさせるため、ここではScheduledExecutorServiceを使ってみた。
再描画させるときにポイントなるのは13行目のpostInvalidate()メソッドである。本来UIスレッド上からViewを再描画するならば、invalidate()メソッドを使えばよい。
しかし、今回の場合は別スレッド上からの再描画となるため、postInvalidate()メソッドを使わなければならない。このメソッドを別スレッドから呼び出すと、UIスレッドでinvalidate()を実行してくれる。
そして、ActivityのonResume()とonPause()のタイミングでスレッドの生成と停止ができるように、onResume()とonPause()というメソッドをpublicで作っておいた。
最後に、Activityのプログラムは以下のようになる。
public class MainActivity extends Activity { private MyView myView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); myView = new MyView(this); setContentView(myView); } // 停止 @Override protected void onPause() { super.onPause(); myView.onPause(); } // 再開 @Override protected void onResume() { super.onResume(); myView.onResume(); } }
プログラムを実行すると、図形がゆっくりと右へ移動していく。
図形が表示範囲の外に出た後の処理など何も施していないが、後はここから色々と応用できるだろう。
ピンバック: 【Android】自前のアニメーション 応用例 – ザワプロ!
ピンバック: 【Java】定期的に処理を実行する – ザワプロ!