viewpage切换动画

近来闲得无聊,觉得有必要学习下viewpage的切换动画效果。

首先是先阅读官网对于viewpage动画的说明和demo:http://developer.android.com/training/animation/screen-slide.html

对于官网给出的demo我已无力吐槽了。。。

所以还是根据官网的Demo自己修改下吧!


省去布局文件,我们直接上Fragment的代码,主要用来显示,没有什么代码,很简单,不解释。

/**
 * Created by victor on 2016/5/12.
 */
public class ScreenSlidePageFragment extends Fragment {

    public static ScreenSlidePageFragment newInstance(int redId) {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        Bundle bundle = new Bundle();
        bundle.putInt("tag", redId);
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        Bundle bundle = getArguments();
        ImageView imageView = new ImageView(getContext());
        if (bundle != null) {
            imageView.setImageResource(bundle.getInt("tag"));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        }
        return imageView;
    }
}


接下来才是我们要看的重头戏。

先是简单的viewpage布局

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

然后是我们的主控制器ScreenSlidePagerActivity,用来控制Fragment的切换,也就是上面的图片的显示切换效果;

import android.support.v4.app.FragmentActivity;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;

import com.example.viewpageanim.com.example.viewpageanim.transformer.ScaleInTransformer;


public class ScreenSlidePagerActivity extends FragmentActivity {

    private static final int IMAGES[] = {R.drawable.a, R.drawable.b, R.drawable.c, R.drawable.d, R.drawable.e, R.drawable.f};
    /**
     * 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);
        mPager.setCurrentItem(1); // 默认显示第二页,当然显示页数至少需要2
mPager.setPageTransformer(true, new ScaleInTransformer()); } /** * 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 ScreenSlidePageFragment.newInstance(IMAGES[position]); } @Override public int getCount() { return NUM_PAGES; } }}

代码量很少,但是却实现了我们常用的轮播图效果。

下面我们来具体分析下。

onCreate中对pageview实例化,然后设置对应的Adapter,最后设置我们需要自定义的动画接口类ZoomOutPageTransformer 

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

    mPager = (ViewPager) findViewById(R.id.pager);
    mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
    mPager.setAdapter(mPagerAdapter);
    mPager.setOffscreenPageLimit(3);
    mPager.setPageTransformer(true, new ZoomOutPageTransformer());
    mPager.setCurrentItem(1); // 默认显示第二页,当然显示页数至少需要2
}

而ScreenSlidePagerAdapter中设置了固定的5页图片显示,很简单,没什么好说的

另外我们最好再设置一下viewpage的缓存个数:

mPager.setOffscreenPageLimit(3);//设置缓存的页面数量

接下来就是来实现我们的PageTransformer接口了。


先看效果图:





不多说,上代码:

import android.annotation.TargetApi;
import android.os.Build;
import android.support.v4.view.ViewPager;
import android.view.View;


/**
 * Created by Victor on 2016/5/13.
 */
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
    
private static final float MIN_SCALE = 0.75f;
    private static final float DEFAULT_MAX_ROTATE = 12.0f;
    private static final float MIN_ALPH = 0.4f;

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    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) {
            if (position < 0) //[0,-1] ;[-1,0]
            {
                float scaleFactor = MIN_SCALE + (1 + position) * (1 - MIN_SCALE) ;
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

                float alphFactor = MIN_ALPH + (1 + position) * (1 - MIN_ALPH) ;
                view.setAlpha(alphFactor);

                view.setRotation(DEFAULT_MAX_ROTATE * position);

            } else //[0,1] ;[1,0]
            {
                float scaleFactor = MIN_SCALE + (1 - position) * (1 - MIN_SCALE);
                view.setScaleX(scaleFactor);
                view.setScaleY(scaleFactor);

                float alphFactor = MIN_ALPH + (1 - position) * (1 - MIN_ALPH) ;
                view.setAlpha(alphFactor);

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


这就是根据谷歌官网给的滑动缩放动画类修改后的动画效果,其中包括alph变化效果、缩放效果和旋转效果。要实现pageview的动画效果,我们必须实现接口

ZoomOutPageTransformer implementsViewPager.PageTransformer;

然后设置mPager.setPageTransformer(new ZoomOutPageTransformer());


看完代码后,下面我们来解释下pageview的position区间是什么意思。

动画的整个区间范围是[-Infinity,+Infinity],这个范围又分为3个小范围。

--为了方便分析,我们假设有A、B、C三页,设置默认显示第二页B--

mPager.setCurrentItem(1); // 默认显示第二页,当然显示页数至少2

区间[-Infinity, -1)对应的是第一页A不可见视图;

区间[1, + Infinity)对应的是第三页C不可见视图;

区间[-1,1]就是我们在滑动过程中出现的两页视图

注意:这里默认pageview的属性android:clipChildren="true",所以当动画停下来后,pageview只有当前页可见。

而对于android:clipChildren="false"的情况需要另外分析。我们先从简单的入手。



所以现在我们关心的就是[-1,1]区间的动画怎么实现。[-1,1]区间又可以分为两个部分:

手势:向右滑动

[-1,0)区间,即将出现的是A页,此时的动画是A页的动画。

那么(0,1]区间,则表示的是B页正在向右消失,此时是B页的动画。

手势:向左滑动

(0, -1]区间,表示的是B页正在向左消失,此时是B页的动画。

那么[1,0)区间,则表示的是C页正在向左,此时是C页的动画。

需要注意的是,不同的手势,[-1,1]区间的变化范围不同。网上有部分资料对于区间[-1,1]的解释有误,或混乱!

搞清楚了[-Infinity,+Infinity]区间的意义,那么写动画就方便多了。


看完之后,你的脑袋里是否有Ding的一一声呢?赶紧打开死丢丢,打造出一个属于你的ViewPage切换效果吧!


另外,我们注意到Viewpage是在3.0之后引入的,所以对于3.0之前的版本没有效果。但是已经有大神给出了解决方案,

那就是使用nineoldandroids来实现动画效果,自定义ViewPage。


源码都在上面了,就不上传了。

如分析有问题,欢迎回复讨论。


内容参考连接:http://blog.csdn.net/lmj623565791/article/details/51339751,感谢鸿洋大神

http://blog.csdn.net/lmj623565791/article/details/40411921/ 解决viewpage版本的向下兼容问题

https://github.com/luhaoaimama1/Zbanner


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值