Android Animations(二):使用ViewPager实现多屏滑动(Screen Slides)

使用ViewPager 实现多屏滑动(Screen Slides)

原文链接

本篇博文介绍如何使用ViewPager 实现屏幕滑动。下面是其动画效果展示:
Screen Slides

  • 创建新项目,并且创建下面四个文件
    • src/ScreenSlidePageFragment.java
    • src/ScreenSlideActivity.java
    • layout/activity_screen_slide.xml
    • layout/fragment_screen_slide_page.xml

创建视图

创建一个布局文件,你可以在其添加一个Fragment 用来展示内容。我们的例子使用了TextView 来展示文本内容:

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

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

创建Fragment

创建一个Fragment,只需要实现onCreateView() 方法。当你需要向用户展示一个新的page时,只需在父Activity 创建一个新的实例:

import android.support.v4.app.Fragment;
...
public class ScreenSlidePageFragment extends Fragment {

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

        return rootView;
    }
}

添加ViewPager

ViewPager 内置了滑动手势,可以进行页面的切换,并且将Screen Slides 作为其默认的动画效果,所以你不需要创建其他任何代码。ViewPager 使用PagerAdapter 来展示新的页面,PagerAdapter将会使用刚刚创建的Fragment

首先,创建一个包含ViewPager 的布局文件:

<!-- activity_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" />

创建一个Activity,对其进行以下操作:

  • 将其content view 设置为ViewPager 的布局文件。
  • 创建一个Adapter 继承 FragmentStatePagerAdapter,覆写getItem() 方法用来返回Page 实例,以及getCount() 方法,返回Page 数量。

  • PagerAdapterViewPager 连接。

  • 监听设备返回键,当用户点击时,返回之前的页面 ,如果已经是第一个页面,则返回之前的Activity

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
...
public class ScreenSlidePagerActivity extends FragmentActivity {
    /**
     * The number of pages (wizard steps) to show in this demo.
     */
    private static final int NUM_PAGES = 5;

    /**
     * The pager widget, which handles animation and allows swiping horizontally to access previous
     * and next wizard steps.
     */
    private ViewPager mPager;

    /**
     * The pager adapter, which provides the pages to the view pager widget.
     */
    private PagerAdapter mPagerAdapter;

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

        // Instantiate a ViewPager and a PagerAdapter.
        mPager = (ViewPager) findViewById(R.id.pager);
        mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(mPagerAdapter);
    }

    @Override
    public void onBackPressed() {
        if (mPager.getCurrentItem() == 0) {
            // If the user is currently looking at the first step, allow the system to handle the
            // Back button. This calls finish() on this activity and pops the back stack.
            super.onBackPressed();
        } else {
            // Otherwise, select the previous step.
            mPager.setCurrentItem(mPager.getCurrentItem() - 1);
        }
    }

    /**
     * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
     * sequence.
     */
    private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }

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

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

使用PageTransformer 实现ViewPager自定义动画效果

为了实现与默认滑动动画不同的动画效果,需要实现ViewPager.PageTransformer 接口。该接口向外只暴露一个方法–transformPage()。当屏幕的任何一个点进行了移动,任何可见的页面以及刚刚消失的页面都会调用这个方法。例如,如果第三个页面可见,并且用户将其向第四个页面进行拖动,则第二个,第三个,第四个页面都会调用一次transformPage() 方法。

实现了transformPage() 方法以后,就可以创建自定义的滑动动画。根据页面在屏幕中显示的位置,决定哪个页面将会被移动。transformPage() 方法中包含 position 参数。

position 参数表示当前页面相对于屏幕中心的位置。当用户滑动时,该参数动态的变化。当屏幕完整的显示时,position 的值为0 ,当屏幕刚刚被拉出右侧屏幕时,position 的值为1 。如果用户将Page 拖动到一半,此时Page 1Page 2各显示一半,则Page 1position 值为-0.5Page 2position 值为0.5 。根据position 值,可以通过setAlpha()setTranslationX()setScaleY()等方法创建自定义的动画效果。

通过调用setPageTransformer() 方法,可以设置自定义动画效果。

下面举两个例子:

Zoom-out动画效果

Zoom-out

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.85f;
    private static final 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)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 1) { // [-1,1]
            // Modify the default slide transition to shrink the page as well
            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);
            }

            // Scale the page down (between MIN_SCALE and 1)
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

            // Fade the page relative to its size.
            view.setAlpha(MIN_ALPHA +
                    (scaleFactor - MIN_SCALE) /
                    (1 - MIN_SCALE) * (1 - MIN_ALPHA));

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

Depth动画效果

Depth

Note: During the depth animation, the default animation (a screen slide) still takes place, so you must counteract the screen slide with a negative X translation. For example:

在Depth动画效果执行期间,默认的Screen Slide 动画效果仍然在执行,必须抵消掉X轴方向上的滑动效果,例如:

view.setTranslationX(-1 * view.getWidth() * position);

完整代码如下:

public class DepthPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.75f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);

        } else if (position <= 1) { // (0,1]
            // Fade the page out.
            view.setAlpha(1 - position);

            // Counteract the default slide transition
            view.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值