package com.example.android.recipe104;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class SakuraWallpaperService extends WallpaperService {
private final Handler mHandler = new Handler();
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
}
// onCreateEngineでEngineを返します。
@Override
public Engine onCreateEngine() {
return new SakuraEngine();
}
// 描画を担当するEngineです。
public class SakuraEngine extends Engine {
private Bitmap image; // イメージ
private int x = 0; // X座標
private int y = 0; // Y座標
private int vx = 10; // X速度
private int vy = 10; // Y速度
private int width;
private int height;
// 描画スレッド
private final Runnable mDrawThread = new Runnable() {
public void run() {
drawFrame();
}
};
// 表示状態フラグ
private boolean mVisible;
//コンストラクタ
public SakuraEngine() {
// リソースからイメージをロードしておきます。
image = BitmapFactory.decodeResource(getResources(),
R.drawable.sakura);
}
// Engine生成時に呼び出される
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
setTouchEventsEnabled(true);
}
// Engine破棄時に呼び出される
@Override
public void onDestroy() {
super.onDestroy();
mHandler.removeCallbacks(mDrawThread);
}
// 表示状態変更時に呼び出される
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
drawFrame();
} else {
mHandler.removeCallbacks(mDrawThread);
}
}
// サーフェイス変更時に呼び出される
@Override
public void onSurfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
this.width = width;
this.height = height;
drawFrame();
}
// サーフェイス生成時に呼び出される
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
super.onSurfaceCreated(holder);
}
// サーフェイス破棄時に呼び出される
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mDrawThread);
}
// オフセット変更時に呼び出される
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xStep, float yStep, int xPixels, int yPixels) {
drawFrame();
}
@Override
public void onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
vx =- vx;
vy =- vy;
}
}
// フレームの描画
private void drawFrame() {
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
// Canvasをロック!
c = holder.lockCanvas();
if (c != null) {
// 描画
c.drawColor(Color.WHITE);
c.drawBitmap(image, x, y, null);
}
} finally {
// Canvasをアンロック!
if (c != null) holder.unlockCanvasAndPost(c);
}
// 跳ね返りの計算
// 左端か右端に達したらx方向の移動を反転
if (x < 0 || width - image.getWidth() < x) {
vx=-vx;
}
// 上端か下端に達したらy方向の移動を反転
if (y < 0 || height - image.getHeight() < y) {
vy=-vy;
}
// 次の座標を計算
x += vx;
y += vy;
// 次の描画をセット(以下は100ms)
mHandler.removeCallbacks(mDrawThread);
if (mVisible) mHandler.postDelayed(mDrawThread, 100);
}
}
}