ページをめくる

Android Tips

本をめくるように指でなぞることでページを切り替えるには、ViewFlipperクラスを使用します。ViewFlipperを使うことでページごとにいちいちActivityを作らず、ビューを切り替えることができます。
「めくる」という指の動きは、指で押した座標と指を離した座標を比較することで判断します。タッチイベントの詳細については、以下を参照のこと。
Viewのタッチイベント

ページを切り替える際にアニメーションさせることもできます。アニメーションの詳細については、以下を参照のこと。
Tweenアニメーション

下の例では、3枚の画像(image_sample1.png、image_sample2.png、image_sample3.png)が指の動きで切り替わっていきます。

import android.app.Activity;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.view.View.OnTouchListener;
import android.widget.ViewFlipper;

public class MyClass extends Activity implements OnTouchListener{

  private ViewFlipper vf_ = null;
  private float lastX_ = 0.0f;

  private Animation leftIn_ = null; // 左から入ってくるアニメーション
  private Animation rightIn_ = null; // 右から入ってくるアニメーション
  private Animation leftOut_ = null; // 左へ抜けるアニメーション
  private Animation rightOut_ = null; // 右へ抜けるアニメーション

  public void myMethod(){
    vf_ = (ViewFlipper)this.findViewById(R.id.vfp_switcher);
    vf_.setDisplayedChild(0); // 1ページ目に設定
    vf_.setOnTouchListener(this);

    Animation leftIn_ = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT,-1.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f);
    leftIn_.setDuration(350);
    Animation rightIn_ = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT,1.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f);
    rightIn_.setDuration(350);
    Animation leftOut_ = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,-1.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f);
    leftOut_.setDuration(350);
    Animation rightOut_ = new TranslateAnimation(
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,1.0f,
      Animation.RELATIVE_TO_PARENT,0.0f,
      Animation.RELATIVE_TO_PARENT,0.0f);
    rightOut_.setDuration(350);
  }

  public boolean onTouch(View v,MotionEvent event){
    switch(event.getAction()){
      case MotionEvent.ACTION_DOWN:
        lastX_ = event.getX();
        break;

      case MotionEvent.ACTION_UP:
        float currentX = event.getX();
        if(currentX - lastX_ > 10){ // 指を10px以上右方向にスライド
          vf_.setInAnimation(leftIn_); // 次ページは左から入ってきて
          vf_.setOutAnimation(rightOut_); // 現ページは右へ抜ける
          vf_.showNext(); // 次ページへ
        }else if(lastX_ - currentX > 10){ // 指を10px以上左方向にスライド
          vf_.setInAnimation(rightIn_); // 次ページは右から入ってきて
          vf_.setOutAnimation(leftOut_); // 現ページは左へ抜ける
          vf_.showPrevious(); // 前ページへ
        }
        break;
    }
  }
} 

ViewFlipperタグに囲まれた3つのImageViewがページに相当します。

res/layout/main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
>
<LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_weight="1"
  android:gravity="center"
  android:orientation="vertical"
>
<ViewFlipper
  android:id="@+id/vfp_switcher"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:layout_gravity="center"
>
<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:scaleType="center"
  android:src="@drawable/image_sample1"
/>
<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:scaleType="center"
  android:src="@drawable/image_sample2"
/>
<ImageView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:scaleType="center"
  android:src="@drawable/image_sample3"
/>
</ViewFlipper>
</LinearLayout>
</LinearLayout>

参考: 遷移先へ値を渡す
参考: 遷移元へ値を返す
参考: オブジェクトの受け渡し

コメント