Adsense_top

2010年6月6日日曜日

[Android] Activityの表示アニメーション

久しぶりのプログラミングネタです。すっかりDesireにハマり、遊びすぎました。(Desireネタ、まだまだ続くとは思います。)


よくCMや動画で見るiPhoneやXperiaの画面が横からスライドしてフェードインしてくる奴がしたかったので、探して出来るようになったので、書いておきます。

基本的な事は、「adamrocker」様のブログ「throw Life」の「ActivityのOpenとCloseをアニメーションさせる」を参考(パクリ?)にさせていただきました。


あまり速く切り替わると動作が解りにくいので、少しゆっくり動くようにしています。
私自身がまだまだAndroid初心者ですので、出来るだけ簡潔に、また参考ページからコピってくるのではなく、書かれているコードの意味を調べつつ書いていますので、コメントが多くて見づらい点はご容赦下さい
 もし、実際に動かしてみる場合、該当のファイル、フォルダが無い場合は作って下さい。またパッケージ名、各クラスのソースファイルを入れるフォルダパスは「・・・」で書いていますので、ご自身の使用パッケージ名に合わせて書き換えて下さい。


2つのActivityの切り替え時にアニメーションするようにしますので、Activityクラスの派生クラスFirstActivity と SecondActivityを作成します。


親のActivity
・./src/・・・/FirstActivity

package ・・・.ActivityAnimation;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class FirstActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first);
// ボタンをひとつ配置
Button toBtn = (Button)findViewById(R.id.to_second);
// クリックイベントで、SecondActivityを起動
toBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =new Intent();
intent.setClass(FirstActivity.this, SecondActivity.class);
startActivity(intent);
}
});
}
}


子のActivity
・./src/・・・/SecondActivity

package ・・・.ActivityAnimation;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
// ボタンをひとつ配置
Button backToBtn = (Button)findViewById(R.id.back_to_first);
// クリックイベントで、このActivityを終了
backToBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}


次に各ActivityのレイアウトXMLを以下のようにします。


親Activityのレイアウト
・res/layout/First.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff000000"
android:gravity="center"
>

<Button android:text="To Second"
android:id="@+id/to_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</Button>
</LinearLayout>


子Activityのレイアウト
・res/layout/Second.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffffff"
android:gravity="center"
>
<Button android:text="Back To First"
android:id="@+id/back_to_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
</Button>
</LinearLayout>


基本部分はActivityの中心にボタンを配置しており、2つとも同じです。違いは、ボタンの文字が「To Second」/「Back To First」の違いと、Activityの背景色が「白」/「黒」の違いだけです。現在表示中のActivityが判別し易くしているだけです。


次はstring.xmlです。


・res/vaslues/string.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">アクティビティーアニメーション</string>
<string name="activity_name1">FirstActivity</string>
<string name="activity_name2">SecondActivity</string>
</resources>


これは見たまんま、名前を設定ているだけです。


アプリケーション内のActivityに適用するテーマを指定します。
・res/values/theme.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AnimationTheme" parent="android:Theme">
<item
name="android:windowAnimationStyle">@style/AnimationActivity</item>
</style>
</resources>


テーマ名を AnimationTheme とし、AnimationActivityをスタイルとして使用する。


上記のテーマで使用するスタイルを定義します。
・res/values/style.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AnimationActivity" parent="android:Animation.Activity">
<item
name="android:activityOpenEnterAnimation">@anim/alpha_open_enter</item>
<item
name="android:activityOpenExitAnimation">@anim/alpha_open_exit</item>
<item
name="android:activityCloseEnterAnimation">@anim/alpha_close_enter</item>
<item
name="android:activityCloseExitAnimation">@anim/alpha_close_exit</item>
</style>
</resources>


スタイル名を AnimationActivity として、使用するアニメーションの指定を行っています。


スタイルで使用される、SecondActivityが開く時のFirstActivityのアニメーションを定義します。
・res/anim/open_exit.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%"
android:toXDelta="-100%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


FirstActivityのX座標を 0% の位置から、 -100% の位置に 300ミリ秒 掛けて移動する。(左側に消えていくイメージ)
fromXDelta:開始 X 座標を % で表記
toXDelta:終了 X 座標を % で表記
duration:開始から終了までの時間間隔(ミリ秒)
下記の二つの属性の意味は、英文の翻訳および動作させた感じからの想像です。あくまでも「たぶん」です。
fillAfter:アニメーション終了時の状態を保持する時は「true」にするそうです。
fillEnabled:「fillAfter」「fillBefor」を適用するかどうかの指示のようです。


スタイルで使用される、SecondActivityが開く時のアニメーションを定義します。
・res/anim/open_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="100%"
android:toXDelta="0%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


SecondActivityのX座標を 100% の位置から、 0% の位置に 300ミリ秒 掛けて移動する。(右から滑って入ってくるイメージ)



スタイルで使用される、SecondActivityが閉じる時のアニメーションを定義します。
・res/anim/close_exit.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%"
android:toXDelta="100%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


SecondActivityのX座標を 0% の位置から、 100% の位置に 300ミリ秒 掛けて移動する。(右側に滑って消えていくイメージ)


スタイルで使用される、SecondActivityが閉じる時のFirstActivityのアニメーションを定義します。
・res/anim/close_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="-100%"
android:toXDelta="0%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


FirstActivityのX座標を -100% の位置から、 0% の位置に 300ミリ秒 掛けて移動する。(左側に滑って入ってくるイメージ)


ここまで書いた内容は、ほぼ参考にした「throw Life」(http://www.adamrocker.com/blog/)の焼き直しです。


ここまで、出来たら一度動かしてしてみてください。
入ってくる新しい画面に押し出される様に前の画面が反対側にスライドしていきます。


 


次に「res/anim/」のアニメーションを定義した4ファイルを以下のように書き換えます。「fromXDelta」と「toXDelta」の値を書き換えています。


・res/anim/open_exit.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%"
android:toXDelta="0%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


FirstActivityはアニメーションの最初から最後までX座標は「0」に固定したままです。


・res/anim/open_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="100%"
android:toXDelta="0%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


SecondActivityのX座標を 100% の位置から、 0% の位置に 300ミリ秒 掛けて移動する。(右から滑って入ってくるイメージ)


・res/anim/close_exit.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%"
android:toXDelta="100%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


SecondActivityのX座標を 0% の位置から、 100% の位置に 300ミリ秒 掛けて移動する。(右側に滑って消えていくイメージ)


スタイルで使用される、SecondActivityが閉じる時のFirstActivityのアニメーションを定義します。
・res/anim/close_enter.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<translate android:fromXDelta="0%"
android:toXDelta="0%"
android:duration="300"
android:fillAfter="true"
android:fillEnabled="true"/>
</set>


FirstActivityはアニメーションの最初から最後までX座標は「0」に固定したままです。
(左側に滑って入ってくるイメージ)


書き変えたら、もう一度動かしてみると、動作が変わっているはずです。


新しい方の画面が前の画面に被さるように入ってきます。出て行く時はそ逆にスライドしていきます。
こちらの方が、iPhoneなどのCMで観る動きに近い感じになります。


次回も、このソースを基に遊んでみます。


--- - --- - --- - --- - --- - --- - --- - --- - --- - --- - --- - --- - --- - -


動作を確認していただくために動画をYouTubeにでも上げようかと思いましたが、上手く動画を撮れなかったため断念しました。実機またはエミュレータから綺麗に撮れる方法をご存知の方が居られましたらお教え下さい。


 


3 件のコメント:

  1. xmlファイル名が間違えてるよ

    返信削除
  2. ・res/vaslues/string.xml <-「vaslues」の部分のスペル間違いですか?

    返信削除
  3. エラーが出ます

    返信削除