画像をアニメーションさせるタイミングを制御したい

479 views
Skip to first unread message

sep7

unread,
Aug 6, 2010, 5:34:04 AM8/6/10
to 日本Androidの会
はじめまして。sep7と申します。

Android端末を振った際に画像がアニメーションするプログラムを作成しているのですが、
Androidを振る度に画像をアニメーションさせるという動きを作れずに困っています。
良い方法をご存知の方がいらっしゃいましたら、ご教授お願いします。

アニメーションはXMLでanimation-listを使って定義しており、
それをプログラム起動時に読み込んで、端末が振られてモーションセンサーが反応すると、
アニメーションをスタートさせる、というようにコードを書いています。

現状、XMLのanimation-listで、android:oneshotにfalseを設定しているのですが
それだと画像アニメーションが1度端末を振った際に動いたままになってしまいます。
これをtrueにすればアニメーションは1度だけ動作してくれるのですが、
それ以降、端末を振ったタイミングで動作しません。

何か良い方法等、アドバイスお願いします。


【アニメーションを定義しているXML】
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/
android"
android:oneshot="false" android:variablePadding="false">
<item android:drawable="@drawable/huu" android:duration="500" />
<item android:drawable="@drawable/huu2" android:duration="500" />
<item android:drawable="@drawable/huu" android:duration="500" />
</animation-list>

【javaソースの該当部分】
@Override
public void onCreate(Bundle icicle) {
 super.onCreate(icicle);
 requestWindowFeature(Window.FEATURE_NO_TITLE);

 // xmlで定義したレイアウト読み込み
 View v = this.getLayoutInflater().inflate(R.layout.main, null);
 setContentView(v);

 // アニメーションリソースをロード
 ImageView image = (ImageView) findViewById(R.anim.anim);
 image.setBackgroundResource(R.anim.anim);
 animation = (AnimationDrawable) image.getBackground();

 // センサーマネージャの取得
 sensorManager = (SensorManager)
getSystemService(Context.SENSOR_SERVICE);
}

// センサーリスナーの処理
@Override
public void onSensorChanged(SensorEvent event) {
// 加速度センサーの値を取得
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
currentAccelerationValues[0] = event.values[SensorManager.DATA_X]
- currentAccelerationValues[0];
currentAccelerationValues[1] = event.values[SensorManager.DATA_Y]
- currentAccelerationValues[1];
currentAccelerationValues[2] = event.values[SensorManager.DATA_Z]
- currentAccelerationValues[2];
}
// 傾きセンサーの値を取得する
if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
currentOrientationValues[0] = event.values[SensorManager.DATA_X]
- currentOrientationValues[0];
currentOrientationValues[1] = event.values[SensorManager.DATA_Y]
- currentOrientationValues[0];
currentOrientationValues[2] = event.values[SensorManager.DATA_Z]
- currentOrientationValues[0];
}

// センサーより取得した値の絶対値を求めて、端末が振られたかどうか判断する。
float targetValue = Math.abs(currentAccelerationValues[0])
+ Math.abs(currentAccelerationValues[1])
+ Math.abs(currentAccelerationValues[2]);
try {
Handler processHandler = new Handler();
Runnable processRunnable = new Runnable() {
public void run() {
waitFlag = false;
}
};

// 一定以上の振り幅で端末が振られた時、音声再生と画像を動かす処理を行う。
if (targetValue > 19.0f) {
if (!waitFlag) {
shakeCnt++;
if (maximumValue < targetValue) {
maximumValue = targetValue;
} else {
ringin();
animation.start();
waitFlag = true;
maximumValue = 0;
processHandler.postDelayed(processRunnable, 300);
animation.stop();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

youten

unread,
Aug 6, 2010, 8:00:59 AM8/6/10
to android-g...@googlegroups.com
youtenです。

oneshot="true"を設定した上で、
.setBackgroundResource(null);
.setBackgroundResource(R.anim.anim);
.invalidate();

とか再設定な感じで動いてくれませんかね。

sep7 さんは書きました:

sep7

unread,
Aug 8, 2010, 10:50:00 PM8/8/10
to 日本Androidの会
sep7です。
youtenさん、ご返答有難うございました。

頂いたアドバイスを参考に、invailidate();を使ってメソッドを少し直したところ実現できました。
Handlerを使って、フラグを一定タイミングでfalseにしているので、
そのタイミングでアニメーションさせる背景画像の再描画をさせています。

【修正後】
// 一定以上の振り幅で端末が振られた時、音声再生と画像を動かす処理を行う。
if (targetValue > 19.5f) {
 if (!waitFlag) {
  shakeCnt++;
  if (maximumValue < targetValue) {
 maximumValue = targetValue;
  } else {
   //再生前に一旦停止させる
   animation.stop();
   //音声再生とアニメーション
   ringin();
   animation.start();
   waitFlag = true;
   maximumValue = 0;
   processHandler.postDelayed(processRunnable, 10);
  }
 }else{
  //アニメーションさせる画像の再描画
  image.invalidate();
 }
}

とても助かりました。ありがとうございます。
同じようなことで困っている方の参考にもなればうれしいです。
Reply all
Reply to author
Forward
0 new messages