フリックでページ切り替えをしたい(その2)

前回に作成した HorizontalFlingView ですが、HorizontalFlingView の子 View で TouchEvent を取得しようとすると不都合があることが分かってきました。

onTouchEvent において、ACTION_DOWN を受け取った際に戻り値に ture を返すことで、後に続く ACTION_MOVE や ACTION_UP を受けれるようになります。HorizontalFlingView が ACTION_DOWN に対して true を返してしまうと、子 View では ACTION_UP を受け取れずに様々なタップ操作が行えません。

自作していくことも考えましたが、あるものは使いましょうということで ViewPager を使うことにしました。

Android Support Package を設定する

  1. Eclipse のウィンドウメニューから Android SDK Manager を起動します
  2. Extras > Android Support package をインストールします
  3. プロジェクトの libs フォルダに android-support-v4.jar をコピーします
  4. プロジェクトのビルドパスに android-support-v4.jar を加えます
    • プロジェクトのプロパティー > Javaのビルド・パス > ライブラリータブ選択 > Jar追加

ViewPager を使う

レイアウトの XML(main.xml) を編集します。

<?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" >

    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>


PagerAdapter を継承したクラスを作成します。

public class WaveViewPagerAdapter extends PagerAdapter {

    private final Page[] pages = new Page[] {
            new Page(R.layout.wave_device),
            new Page(R.layout.wave_one),
            new Page(R.layout.wave_line) };

    public WaveViewPagerAdapter(Context context) {
        LayoutInflater inflater =
            (LayoutInflater)context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        for (Page page : pages) {
            page.initView(inflater);
        }
    }

    @Override
    public int getCount() {
        return pages.length;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == (View)object;
    }

    @Override
    public Object instantiateItem(View collection, int position) {
        ViewPager pager = (ViewPager)collection;
        pager.addView(pages[position].getView(), position);
        return pages[position].getView();
    }

    @Override
    public void destroyItem(View collection, int position, Object view) {
        ViewPager pager = (ViewPager)collection;
        pager.removeViewAt(position);
    }

    private static class Page {

        private final int resource;
        private View view;

        Page(int resource) {
            this.resource = resource;
        }

        void initView(LayoutInflater inflater) {
            view = inflater.inflate(resource, null);
        }

        View getView() {
            return view;
        }
    }
}


Activity の onCreate で PagerAdapter を生成して、ViewPager に設定します。

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        ViewPager pager = (ViewPager)findViewById(R.id.pager);
        pager.setAdapter(new WaveViewPagerAdapter(this));
        ...
    }


PagerAdapter インスタンス生成時に子 View を初期化しています。

inflate(resource, null) の呼び出しに、null ではなく pager を渡してみたのですがエラーとなるために null を渡しています。


何か間違えていたらご指摘ください。