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】定期的に処理を実行する – ザワプロ!