ApiDemosを調べる3 - 個別API Animation.Activity

App -> Activity -> Animationについて。
Activity間を遷移する際の表示に動きをつけるもの。
アルファを用いてじわっと出てきたりする。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_animation);

        // Watch for button clicks.
        Button button = (Button)findViewById(R.id.fade_animation);
        button.setOnClickListener(mFadeListener);
        button = (Button)findViewById(R.id.zoom_animation);
        button.setOnClickListener(mZoomListener);
    }

setContentViewはXMLからレイアウトを読み込む。
R.layout.activity_animationはプロジェクトのres/layout/activity_animation.xml以下にある。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
    android:gravity="center_horizontal"
    android:layout_width="match_parent" android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent" android:layout_height="wrap_content"
        android:layout_weight="0"
        android:paddingBottom="4dip"
        android:text="@string/activity_animation_msg"/>

    <Button android:id="@+id/fade_animation"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="@string/activity_animation_fade">
        <requestFocus />
    </Button>

    <Button android:id="@+id/zoom_animation"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:text="@string/activity_animation_zoom">
    </Button>

</LinearLayout>

LinearLayoutは一列に並べるLayout方法。
orientationで垂直方向指定、gravityでcenter揃え。

LinearLayoutの中に3つのWidget(View)が並ぶ。

TextView
 幅は親に合わせて(親=LinearLayout=画面)
 高さはコンテンツにあわせて
 文字はres/values/strings.xmlに定義されている。

    <string name="activity_animation_msg">Press a button to launch an activity with a custom animation.</string>

Button
 幅と高さはコンテンツにあわせて(この場合文字の大きさと数)
 文字は2つのボタンそれぞれについて、

    <string name="activity_animation_fade">Fade in</string>
    <string name="activity_animation_zoom">Zoom in</string>

これで以下のような画面が出力される

XMLからレイアウトを設定した後、今度はそれらの部品を
コードで取得する。findViewById()を用いて、ボタンオブジェクトを取得し、
setOnClickListener()でClickしたときの振る舞いを設定する。

OnClickListener()は以下のように定義する。
ここがこのアプリのポイント。アニメーションによる画面遷移の設定を行っている。

    private OnClickListener mFadeListener = new OnClickListener() {
        public void onClick(View v) {
            // Request the next activity transition (here starting a new one).
            startActivity(new Intent(Animation.this, Controls1.class));
            // Supply a custom animation.  This one will just fade the new
            // activity on top.  Note that we need to also supply an animation
            // (here just doing nothing for the same amount of time) for the
            // old activity to prevent it from going away too soon.
            overridePendingTransition(R.anim.fade, R.anim.hold);
        }
    };

overridePendingTransition()をstartActivity()の直後に呼ぶことで
遷移にAnimation効果を持たせることができる。
第1引数はenterAnim, 第2引数はexitAnimらしい。
enterは新Activityかと。exitは旧Activityかと。

R.anim.fade, R.anim.holdはそれぞれ/res/anim/fade.xml, /res/anim/hold.xml
記載されている。以下のとおり。

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromAlpha="0.0" android:toAlpha="1.0"
       android:duration="@android:integer/config_longAnimTime" />

<translate xmlns:android="http://schemas.android.com/apk/res/android"
       android:interpolator="@android:anim/accelerate_interpolator"
       android:fromXDelta="0" android:toXDelta="0"
       android:duration="@android:integer/config_longAnimTime" />
       

interpolatorは遷移の速さを決める。
accelerate_interppolatorはどんどん早くを意味する。
そのほかは
http://developer.android.com/reference/android/R.anim.htmlで。

durationは遷移の時間を決める。
config_longAnimTimeは遅く。時間[ms]での指定もよいらしい。
そのほかは
http://developer.android.com/reference/android/R.integer.htmlで。

Controls1.classは別途定義された適当なActivityを含む。
具体的には以下のとおり。

public class Controls1 extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.controls_1);

        Spinner s1 = (Spinner) findViewById(R.id.spinner1);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, mStrings);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        s1.setAdapter(adapter);
    }

    private static final String[] mStrings = {
        "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
    };
}

もう1つ、Zoomという遷移がある。

    private OnClickListener mZoomListener = new OnClickListener() {
        public void onClick(View v) {
            // Request the next activity transition (here starting a new one).
            startActivity(new Intent(Animation.this, Controls1.class));
            // This is a more complicated animation, involving transformations
            // on both this (exit) and the new (enter) activity.  Note how for
            // the duration of the animation we force the exiting activity
            // to be Z-ordered on top (even though it really isn't) to achieve
            // the effect we want.
            overridePendingTransition(R.anim.zoom_enter, R.anim.zoom_exit);
        }
    };

XMLでZoomの設定をする。

zoom_enter

<!-- Special window zoom animation: this is the element that enters the screen,
     it starts at 200% and scales down.  Goes with zoom_exit.xml. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/decelerate_interpolator">
    <scale android:fromXScale="2.0" android:toXScale="1.0"
           android:fromYScale="2.0" android:toYScale="1.0"
           android:pivotX="50%p" android:pivotY="50%p"
           android:duration="@android:integer/config_mediumAnimTime" />
</set>

zoom_exit

<!-- Special window zoom animation: this is the element that exits the
     screen, it is forced above the entering element and starts at its
     normal size (filling the screen) and scales down while fading out.
     This goes with zoom_enter.xml. -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/decelerate_interpolator"
        android:zAdjustment="top">
    <scale android:fromXScale="1.0" android:toXScale=".5"
           android:fromYScale="1.0" android:toYScale=".5"
           android:pivotX="50%p" android:pivotY="50%p"
           android:duration="@android:integer/config_mediumAnimTime" />
    <alpha android:fromAlpha="1.0" android:toAlpha="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
</set>

新しいほうのActivityは縮小して本来のサイズへ(200% -> 100%)
消えていくほうは縮小(100% -> 50%)しながら薄くなっていく(Alpha 1.0 -> 0.0)。

以上。