ViewPagerに切り替えのアニメーションを付ける


#ViewPagerに切り替えのアニメーションを付ける

今回はViewPagerに切り替えのアニメーションを付けるサンプルを作ってみました。
[ViewPagerリファレンス](https://developer.android.com/reference/android/support/v4/view/ViewPager.html)


アニメーションを付けるにあたり、
[Using ViewPager for Screen Slides](https://developer.android.com/training/animation/screen-slide.html)　
のサンプルを参考に作成してみました。


```java:ScreenSlideActivity.java

public class ScreenSlideActivity extends FragmentActivity {
    
    private static final int NUM_PAGES = 5;
    private ViewPager mPager;
    private PagerAdapter mPagerAdapter;

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

        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getFragmentManager());
        mPager.setAdapter(mPagerAdapter);
        mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                invalidateOptionsMenu();
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        getMenuInflater().inflate(R.menu.activity_screen_slide, menu);

        menu.findItem(R.id.action_previous).setEnabled(mPager.getCurrentItem() > 0);


        MenuItem item = menu.add(Menu.NONE, R.id.action_next, Menu.NONE,
                (mPager.getCurrentItem() == mPagerAdapter.getCount() - 1) ? R.string.action_finish : R.string.action_next);
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {

            case R.id.action_previous:
                mPager.setCurrentItem(mPager.getCurrentItem() - 1);
                return true;

            case R.id.action_next:
                mPager.setCurrentItem(mPager.getCurrentItem() + 1);
                return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            return ScreenSlidePageFragment.create(position);
        }

        @Override
        public int getCount() {
            return NUM_PAGES;
        }
    }

}

```




```Java:ScreenSlidePageFragment.java

public class ScreenSlidePageFragment extends Fragment {
    
    public static final String ARG_PAGE = "page";
    private int mPageNumber;

    public static ScreenSlidePageFragment create(int pageNumber) {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, pageNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public ScreenSlidePageFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPageNumber = getArguments().getInt(ARG_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_screen_slide_page, container, false);


        ((TextView) rootView.findViewById(android.R.id.text1)).setText(
                getString(R.string.title_template_step, mPageNumber + 1));

        return rootView;
    }

    
    public int getPageNumber() {
        return mPageNumber;
    }
}

```

```xml:fragment_screen_slide.xml
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

```

```xml:fragment_screen_slide_page.xml

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView android:id="@android:id/text1"
            style="?android:textAppearanceLarge"
            android:textStyle="bold"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp" />

        <TextView style="?android:textAppearanceMedium"
            android:lineSpacingMultiplier="1.2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/lorem_ipsum" />

    </LinearLayout>

</ScrollView>

```

動かしてみると、このようになります。

![alt](http://i.giphy.com/jT6vZA2mAnZIs.gif)



#応用


```Java:ScreenSlideActivity.java

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {

    private float MIN_SCALE = 0.85f;
    private float MIN_ALPHA = 0.5f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();
        if (position < -1) { // [-Infinity,-1)
                // このページは左側の画面外にあります。
              view.setAlpha(0);
        } else if (position <= 1) { // [-1,1]
                // デフォルトのスライド遷移もページを縮小するよう修正します。
              float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
              float vertMargin = pageHeight * (1 - scaleFactor) / 2;
              float horzMargin = pageWidth * (1 - scaleFactor) / 2;

              if (position < 0) {

                    view.setTranslationX(horzMargin - vertMargin / 2);

              } else {

                    view.setTranslationX(-horzMargin + vertMargin / 2);

              }
                // ページの大きさを小さくします(MIN_SCALEと1との間)
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

                // ページのサイズと相対的にページの表示を薄くします
                view.setAlpha(MIN_ALPHA +
                        (scaleFactor - MIN_SCALE) /
                                (1 - MIN_SCALE) * (1 - MIN_ALPHA));

            } else { // (1,+Infinity]
                // このページは右側の画面外にあります。
                view.setAlpha(0);
            }
        }
    }

```

ScreenSlideActivity.javaに上のコードを追加すると

![alt](http://i.giphy.com/FNJmlvleeUxi0.gif)

このようになります。


#参考資料
[Using ViewPager for Screen Slides](https://developer.android.com/training/animation/screen-slide.html)　

#協力
この記事はGDG石巻の協力の元作成されました。
[GDG石巻とは？](https://sites.google.com/site/gdgjapan/)

<img src=https://qiita-image-store.s3.amazonaws.com/0/136730/1c367c24-9b44-e959-8b16-2a6d9697cced.png width=350px>