用ViewPage实现不同的滑动效果

给ViewPager滑动加一个动画.

在我之前的博客模仿知乎安卓客户端的banner广告条以及一些思考中有写到利用viewPager的PageTransformer来实现各种不同的viewPager的滑动效果,这次我就写了9种不同的效果来练习一下.
代码在我的 github
这里面用的知识点也不是很多,主要是和view变换有关的
0.View.setAlpha()设置透明度

1. View.setPivotX()设置锚点的X坐标值
2. View.setPivotY()设置锚点的Y坐标值
3. View.setScaleX()设置x轴的缩放系数
4. View.setScaleY()设置Y轴的缩放系数
5. View.setTranslationX()设置在X轴的平移值
6. View.setTranslationY()设置在Y轴的平移值
7. View.setTranslationZ()设置在Z轴的平移值
8. View.setRotationX()设置绕X轴旋转中心的的旋转角度,旋转轴位置可以由View.setPivotY()设置Y轴的旋转中心
9. View.setRotationY()设置绕Y轴旋转中心的的旋转角度,旋转轴位置可以由View.setPivotX()设置X轴的旋转中心
10. View.setRotationZ()设置绕Z轴旋转中心的旋转角度,旋转中心由以上两个设置.

View.setCameraDistance()设置相机距离View的距离,避免产生在绕Y轴或者X轴的旋转时产生画面糊脸的效果,一般要设置大一点.

书籍翻页渐隐


public class BookFlippageFadePageTransormer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position <= -1) {
            /*页面已经在屏幕左侧且不可视*/
            page.setAlpha(position);
        } else if (position <= 0) {
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setAlpha(1 + position);
            page.setPivotY(page.getHeight() / 2);
            page.setPivotX(0);
            page.setCameraDistance(60000);/*调整摄像机的位置,避免出现糊脸的感觉*/
            page.setRotationY((position * 180));
            page.setTranslationX(position * -page.getWidth());
        } else if (position <= 1) {
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setTranslationX(position * -page.getWidth());
        } else if (position > 1) {
            /*页面已经在屏幕右侧且不可视*/
            page.setTranslationX(position * -page.getWidth());
        }
    }
}

翻页旋转


public class FilpPageRotationPageTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) { /* [-Infinity,-1)*/
            /*页面已经在屏幕左侧且不可视*/
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setCameraDistance(60000);
            page.setAlpha(1 + position);
            page.setTranslationX(page.getWidth() * -position);
            page.setPivotX(0);
            page.setRotationY(position * 90);
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setCameraDistance(60000);
            page.setTranslationX(page.getWidth() * -position);
            page.setPivotX(0);
            page.setRotationY(position * 90);
            page.setAlpha(1 - position);
        } else if (position > 1) {
        /*页面已经在屏幕右侧且不可视*/
        }
    }
}

卡片绕中心旋转


public class CardFlipoverPageTransormer implements PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position <= -1) {
            /*页面已经在屏幕左侧且不可视*/
            /*设置离开的page不可点击,不可见*/
            page.setClickable(false);
            page.setAlpha(0);
        } else if (position <= 0) {
            page.setClickable(false);
            /*页面从左侧进入或者向左侧滑出的状态*/
            /*把旋转中心改为中间*/
            page.setAlpha(1);
            if (position <= -0.5)
                /*旋转到中间时该页page隐藏掉*/
                page.setAlpha(0);
            page.setPivotX(page.getWidth() / 2);
            page.setPivotY(page.getHeight() / 2);
            page.setTranslationX(position * -page.getWidth());
            page.setCameraDistance(10000);
            page.setRotationY(position * 180);
        } else if (position <= 1) {
            /*页面从右侧进入或者向右侧滑出的状态*/
            /*初始状态要是隐藏状态*/
            page.setAlpha(0);
            if (position <= 0.5)
                /*旋转到中间时该页page显示出来*/
                page.setAlpha(1);
            page.setPivotX(page.getWidth() / 2);
            page.setPivotY(page.getHeight() / 2);
            page.setTranslationX(position * -page.getWidth());
            page.setCameraDistance(10000);
            page.setRotationY(-180 - (1 - position) * 180);
        } else if (position >= 1) {
                        /*页面已经在屏幕右侧且不可视*/
        }
    }
}

立方体旋转


public class CubesPageTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position <=-1) { /* [-Infinity,-1)*/
        /*页面已经在屏幕左侧且不可视*/
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setCameraDistance(100000);
            page.setPivotX(page.getMeasuredWidth());
            page.setPivotY(page.getMeasuredHeight()*0.5f);
            page.setRotationY(90*position);
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setCameraDistance(100000);
            page.setPivotX(0);
            page.setPivotY( page.getWidth()*(0.5f));
            page.setRotationY(90*position);
        }else if (position >1){
        /*页面已经在屏幕右侧且不可视*/
        }
    }
}

转盘旋转


public class TurntablePageTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) { /* [-Infinity,-1)*/
        /*页面已经在屏幕左侧且不可视*/
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setPivotX(page.getWidth() / 2);
            page.setPivotY(page.getHeight());
            page.setRotation(90*position);
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setPivotX(page.getWidth() / 2);
            page.setPivotY(page.getHeight());
            page.setRotation(90*position);
        } else if (position > 1) {
        /*页面已经在屏幕右侧且不可视*/
        }
    }
}

层叠缩放


public class CascadeZoomPageTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) { /* [-Infinity,-1)*/
        /*页面已经在屏幕左侧且不可视*/
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setAlpha(1 + position);
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setTranslationX(page.getWidth() * -position);
            page.setScaleX(1-position*0.5f);
            page.setScaleY(1-position*0.5f);
            page.setAlpha(1 - position);
        }else if (position >1){
        /*页面已经在屏幕右侧且不可视*/
        }
    }
}

折叠向上


/**
 * Created by M on 2017/9/21.
 * 这个要配和在ViewPager里设置android:clipChildren="false"
 * android:margin="xxdp"
 * 在ViewPager的外层里设置android:clipChildren="false"
 */
public class  DepthCardTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) { /* [-Infinity,-1)*/
        /*页面已经在屏幕左侧第一个*/
            page.setCameraDistance(10000);
            page.setPivotX(page.getWidth()/2);
            page.setPivotY(page.getWidth());
            page.setRotationY(20);
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setCameraDistance(10000);
            page.setPivotX(page.getWidth()/2);
            page.setPivotY(page.getWidth());
            page.setRotationY(-20+(1-position)*20);
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setCameraDistance(10000);
            page.setPivotX(page.getWidth()/2);
            page.setPivotY(page.getWidth());
            page.setRotationY(-20+(1-position)*20);
        } else if (position<=2) {
        /*页面已经在屏幕右侧第一个*/
            page.setCameraDistance(10000);
            page.setPivotX(page.getWidth()/2);
            page.setPivotY(page.getWidth());
            page.setRotationY(-20);
        }
    }
}

滑动缩放


/**
 * Created by M on 2017/9/21.
 * 这个要配和在ViewPager里设置android:clipChildren="false"
 * android:margin="xxdp"
 * 在ViewPager的外层里设置android:clipChildren="false"
 */
public class ZoominPagerTransFormer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View page, float position) {
        if (position < -1) { /* [-Infinity,-1)*/
        /*页面已经在屏幕左侧且不可视*/
            page.setScaleX((float) (1 + position * 0.1));
            page.setScaleY((float) (1 + position * 0.1));
        } else if (position <= 0) { /* [-1,0]*/
            /*页面从左侧进入或者向左侧滑出的状态*/
            page.setScaleX((float) (1 + position * 0.1));
            page.setScaleY((float) (1 + position * 0.1));
        } else if (position <= 1) {/* (0,1]*/
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setScaleX((float) (1-  position * 0.1));
            page.setScaleY((float) (1 - position * 0.1));
        } else if (position > 1) {
        /*页面已经在屏幕右侧且不可视*/
            page.setScaleX((float) (1-  position * 0.1));
            page.setScaleY((float) (1 - position * 0.1));
        }
    }
}

卡片堆叠


public class CardStackPaegTransformer implements ViewPager.PageTransformer {
    public void transformPage(View page, float position) {
        if (position <= -1) {
         /*页面已经在屏幕左侧且不可视*/
        } else if (position <= 0) {
        /*页面从左侧进入或者向左侧滑出的状态*/
        } else if (position < 1) {
            /*页面从右侧进入或者向右侧滑出的状态*/
            page.setAlpha((float) (1 - position * 0.1));
            page.setPivotX(page.getWidth() / 2f);
            page.setPivotY(page.getHeight() / 2f);
            page.setScaleX((float) Math.pow(0.9f, position));    /*0.9f为缩放系数*/
            page.setScaleY((float) Math.pow(0.9f, position));
            page.setTranslationX(position * -page.getWidth());
            page.setTranslationY(-position * 70);/*70每层card的Y轴间隔*/
        } else if (position >= 1) {
            /*页面已经在屏幕右侧且不可视*/
            page.setAlpha((float) (1 - position * 0.1));
            page.setPivotX(page.getWidth() / 2f);
            page.setPivotY(page.getHeight() / 2f);
            page.setScaleX((float) Math.pow(0.9f, position));
            page.setScaleY((float) Math.pow(0.9f, position));
            page.setTranslationX(position * -page.getWidth());
            page.setTranslationY(-position * 70);
        }
    }
}

卡片堆叠 进阶版


这个进阶版可以看到是在滑动结束后有一个弹跳的类似于果冻动画,这个实际上我是对Viewpage设置了滑动监听,在滑动状态改变时对当前的page设置一个缩放动画,这样就好了
下面是果冻动画的代码,这里安利一个网站inloop.github.io/interpolato…,这个网站可以直观看到不同插值器的曲线变化情况,我的这个插值器也是在这里经过调整之后得到的.

/*配合以下代码可以实现滑动结束后的果冻效果*/
int mCurrentPosition=0;
float mFactor = 0.5f;
mAnimation = new ScaleAnimation(0.9f, 1.0f, 0.9f, 1.0f, 150, 450);
        mAnimation.setDuration(500);
        mAnimation.setFillAfter(true);
        mAnimation.setInterpolator(new Interpolator() {
            @Override
            public float getInterpolation(float input) {
                return (float) (Math.pow(2, -10 * input) * Math.sin((input - mFactor / 4) * (2 * Math.PI) / mFactor) + 0.9);
            }
        });
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                Log.d("MainActivity", "onPageScrolled: position" + position + " positionOffset" + positionOffset + " positionOffsetPixels" + positionOffsetPixels);
            }
            @Override
            public void onPageSelected(int position) {
                Log.d("MainActivity", "onPageSelected: position" + position);
                 mImageViewList.get(mCurrentPosition ).clearAnimation();/*//把上一个page的动画取消掉*/
                mCurrentPosition = position;/*更新当前的page位置*/
                mImageViewList.get(mCurrentPosition).startAnimation(mAnimation);/*开始动画*/
            }
            @Override
            public void onPageScrollStateChanged(int state) {
                Log.d("MainActivity", "onPageScrollStateChanged: state" + state);
            }
        });


好的,下面是使用ViewPager和TabLayout实现滑动效果的步骤: 1.在布局文件中添加ViewPager和TabLayout组件 ```xml <android.support.design.widget.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" app:tabMode="scrollable" app:tabTextColor="@android:color/white" app:tabSelectedTextColor="@android:color/white" app:tabIndicatorColor="@android:color/white" app:tabIndicatorHeight="3dp" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 2.在Java代码中初始化ViewPager和TabLayout组件 ```java ViewPager viewPager = findViewById(R.id.viewPager); TabLayout tabLayout = findViewById(R.id.tabLayout); MyFragmentPagerAdapter adapter = new MyFragmentPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); tabLayout.setupWithViewPager(viewPager); ``` 3.实现FragmentPagerAdapter类,用于管理ViewPager中的Fragment ```java public class MyFragmentPagerAdapter extends FragmentPagerAdapter { private String[] titles = {"Tab 1", "Tab 2", "Tab 3"}; public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { switch (position) { case 0: return new Fragment1(); case 1: return new Fragment2(); case 2: return new Fragment3(); default: return null; } } @Override public int getCount() { return titles.length; } @Nullable @Override public CharSequence getPageTitle(int position) { return titles[position]; } } ``` 4.实现三个Fragment类,用于显示在ViewPager中的内容 ```java public class Fragment1 extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment1_layout, container, false); return view; } } public class Fragment2 extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment2_layout, container, false); return view; } } public class Fragment3 extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment3_layout, container, false); return view; } } ``` 5.创建三个布局文件fragment1_layout.xml、fragment2_layout.xml、fragment3_layout.xml,用于显示在ViewPager中的内容 ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="Fragment 1" android:textSize="30sp" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="Fragment 2" android:textSize="30sp" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="Fragment 3" android:textSize="30sp" android:gravity="center" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout> ``` 以上就是使用ViewPager和TabLayout实现滑动效果的步骤,希望对你有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值