June 4, 2012

ViewFlipperによるView切り替えアニメーション

Viewから別のViewへ切り替えるとき、アニメーション付きで切り替える方法です。ViewFlipperクラスという専用のクラスが用意されており、それを使うと簡単にいろいろなアニメーションでの画面遷移が実現できます。

基本の考えは、ViewFlipperに複数のViewを登録し、それらのViewの間で切り替えができますが、その切り替えのアニメーションはAnimationクラスで設定し、それをInする側とOutする側それぞれに適用することで実現します。

アニメーションは、アルファ、スケール、移動、回転の4種類でタイミングなども細かく設定でき、複数組み合わせることもできます。

例では、3つのViewの切り替えを、アルファと移動を組み合わせたアニメーションで左右にボタンで遷移できるものを作ります。まず最初に完成品の動画から。


最初にアニメーションのxmlを作ります。XMLファイルを作成するとき、Tween Animationのsetを選択します。リソースは自動で、res/animにおかれます。左方向へのIn/Out、右方向へのIn/Outの4パターン必要になります。アニメーションの定義はfromからtoへの状態の変化と、その変化をいつから、どのぐらいの時間で遷移させるか、タイミングの設定を記載します。translateでは画面端から画面中央へ、alphaでは透明0%から100%へ変化させています。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:duration="600" />
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:startOffset="100"
        android:duration="400" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:fromXDelta="0"
        android:toXDelta="-100%"
        android:duration="500" />
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        android:startOffset="100"
        android:duration="400" />
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
        android:duration="500" />
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:startOffset="100"
        android:duration="400" />    
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:fromXDelta="0"
        android:toXDelta="100%"
        android:duration="600" />
    <alpha
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        android:startOffset="100"
        android:duration="400" />
</set>

3つのViewですが、すべて同じViewとします。サブViewとしてレイアウトを作成して、それをメインViewのレイアウトで3つincludeして、それをViewFlipperのView群として登録します。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    <Button
        android:id="@+id/previous"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/previous" />
    <ImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher" />
    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/myname" />
    <Button
        android:id="@+id/next"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="wrap_content"
        android:text="@string/next" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
<ViewFlipper
    android:id="@+id/flipper"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<include
    android:id="@+id/page1"
    layout="@layout/sub" />
<include
    android:id="@+id/page2"
    layout="@layout/sub" />
<include
    android:id="@+id/page3"
    layout="@layout/sub" />
</ViewFlipper>
</LinearLayout>

ソースコードでは最初にAnimationをロードし、ボタンのクリックを登録します。クリックされたら、どちらのボタンを押されたか判定して、ViewFlipperで適切なアニメーションを設定して画面遷移を行います。

public class SampleAppActivity extends Activity implements OnClickListener {
    private final static String TAB = "SampleAppActivity";
    private ViewFlipper mFlipper;
    private Animation mAnimRightIn;
    private Animation mAnimRightOut;
    private Animation mAnimLeftIn;
    private Animation mAnimLeftOut;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        mFlipper = (ViewFlipper) findViewById(R.id.flipper);

        // Load animation
        mAnimRightIn = AnimationUtils.loadAnimation(this, R.anim.right_in);
        mAnimRightOut = AnimationUtils.loadAnimation(this, R.anim.right_out);
        mAnimLeftIn = AnimationUtils.loadAnimation(this, R.anim.left_in);
        mAnimLeftOut = AnimationUtils.loadAnimation(this, R.anim.left_out);

        // Set button click action
        int pages[] = {R.id.page1, R.id.page2, R.id.page3};
        for (int page : pages) {
            LinearLayout layout = (LinearLayout) findViewById(page);
            Button nextButton = (Button) layout.findViewById(R.id.next);
            nextButton.setOnClickListener(this);
            Button previousButton = (Button) layout.findViewById(R.id.previous);
            previousButton.setOnClickListener(this);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.next:
            mFlipper.setInAnimation(mAnimRightIn);
            mFlipper.setOutAnimation(mAnimLeftOut);
            mFlipper.showNext();
            break;
        case R.id.previous:
            mFlipper.setInAnimation(mAnimLeftIn);
            mFlipper.setOutAnimation(mAnimRightOut);
            mFlipper.showPrevious();
            break;
        }
    }
}

参考:Android Developers:ViewFlipper

No comments:

Post a Comment