ViewPager.PageTransformer 的 position 分析

前言

PageTransformer 是 ViewPager 内部定义的接口,实现该接口并通过 setPageTransformer 方法设置后可以实现自定义的 ViewPager 滑动效果。

ViewPager.PageTransformer 的定义

首先看下该接口:

    public interface PageTransformer {
        /**
         * Apply a property transformation to the given page.
         *
         * @param page Apply the transformation to this page
         * @param position Position of page relative to the current front-and-center
         *                 position of the pager. 0 is front and center. 1 is one full
         *                 page position to the right, and -1 is one page position to the left.
         */
        void transformPage(View page, float position);
    }

该接口只有一个方法 transformPage,第一个参数是转换效果应用的页面,第二个参数表示页面的位置,它的注释是这样说的:

相对于中心页面的页面位置,0 表示中间页面,1 表示右侧页面的一整页,-1 表示左侧页面的一整页

光看注释显然不能理解 position 的含义。所以接下来就是打 log 了,看下在移动过程中,position 是怎么变化的。

理解 position

前期准备:

  1. 在 Fragment 的 onCreateView 方法中为创建的 View 设置一个 Tag:
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = ...
        view.setTag(content);   // content 为 Fragment 显示的文本内容,也是 Tab 的 Title

        return view;
    }
  1. 在 transformPage 方法中打印 log:
    mViewPager.setPageTransformer(false, new ViewPager.PageTransformer() {
        @Override
        public void transformPage(@NonNull View view, float v) {
            Log.d(TAG, "view = " + view.getTag() + ", v = " + v);
        }
    });

假设有这几个 ViewPager 页面:

当从左往右滑(从 Java 页面滑动 Android 页面)时,Log 打印结果如下:

2019-11-02 11:12:55.418 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = 0.0
2019-11-02 11:12:55.418 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 1.0
2019-11-02 11:16:16.805 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.016666668
2019-11-02 11:16:16.805 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.98333335
2019-11-02 11:16:16.815 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.09351852
2019-11-02 11:16:16.815 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.9064815
2019-11-02 11:16:16.836 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.20925926
2019-11-02 11:16:16.837 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.7907407
2019-11-02 11:16:16.844 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.33333334
2019-11-02 11:16:16.844 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.6666667
2019-11-02 11:16:16.860 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.43703705
2019-11-02 11:16:16.860 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.56296295
2019-11-02 11:16:16.882 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.6259259
2019-11-02 11:16:16.883 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.37407407
2019-11-02 11:16:16.897 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.7601852
2019-11-02 11:16:16.898 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.23981482
2019-11-02 11:16:16.913 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.8574074
2019-11-02 11:16:16.913 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.1425926
2019-11-02 11:16:16.929 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9203704
2019-11-02 11:16:16.929 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.07962963
2019-11-02 11:16:16.945 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.95648146
2019-11-02 11:16:16.946 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.043518517
2019-11-02 11:16:16.963 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.97962964
2019-11-02 11:16:16.963 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.02037037
2019-11-02 11:16:16.980 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9916667
2019-11-02 11:16:16.980 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.008333334
2019-11-02 11:16:16.996 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.99722224
2019-11-02 11:16:16.997 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.0027777778
2019-11-02 11:16:17.013 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9990741
2019-11-02 11:16:17.013 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 9.259259E-4
2019-11-02 11:16:17.029 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.0
2019-11-02 11:16:17.030 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.0

可以看到 Java 和 Android 页交错显示,把它们整理一下,同一个页面放在一起:

2019-11-02 11:12:55.418 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = 0.0
2019-11-02 11:16:16.805 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.016666668
2019-11-02 11:16:16.815 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.09351852
2019-11-02 11:16:16.836 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.20925926
2019-11-02 11:16:16.844 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.33333334
2019-11-02 11:16:16.860 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.43703705
2019-11-02 11:16:16.882 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.6259259
2019-11-02 11:16:16.897 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.7601852
2019-11-02 11:16:16.913 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.8574074
2019-11-02 11:16:16.929 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9203704
2019-11-02 11:16:16.945 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.95648146
2019-11-02 11:16:16.963 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.97962964
2019-11-02 11:16:16.980 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9916667
2019-11-02 11:16:16.996 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.99722224
2019-11-02 11:16:17.013 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -0.9990741
2019-11-02 11:16:17.029 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.0

2019-11-02 11:12:55.418 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 1.0
2019-11-02 11:16:16.805 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.98333335
2019-11-02 11:16:16.815 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.9064815
2019-11-02 11:16:16.837 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.7907407
2019-11-02 11:16:16.844 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.6666667
2019-11-02 11:16:16.860 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.56296295
2019-11-02 11:16:16.883 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.37407407
2019-11-02 11:16:16.898 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.23981482
2019-11-02 11:16:16.913 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.1425926
2019-11-02 11:16:16.929 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.07962963
2019-11-02 11:16:16.946 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.043518517
2019-11-02 11:16:16.963 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.02037037
2019-11-02 11:16:16.980 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.008333334
2019-11-02 11:16:16.997 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.0027777778
2019-11-02 11:16:17.013 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 9.259259E-4
2019-11-02 11:16:17.030 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = 0.0

可以看到,Java 页面的 position 值由 0 到 -1 变化,而 Android 页面的 position 值由 1 到 0 变化。

如果按照注释所说,0 表示当前页,-1 表示左边页,1 表示右边页。那么 Java 页面是因为由当前页变为左边页,所以 position 值从 0 到 -1 变化,而 Android 页面是因为由右边页变成当前页,所以 position 值从 1 到 0 变化

感觉解释得通,好像是这个道理,是不是真的是这样呢,不妨验证一下,那就再滑动一次。

这次由 Android 页 滑动到 计算机网络页,根据上面的解释,猜测 Android 页的 position 值会从 0 到 -1 变化,计算机网络页的 position 值会从 1 到 0 变化。

结果是不是这样呢?看下整理后的打印结果:

2019-11-02 11:28:22.526 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.0018518
2019-11-02 11:28:22.550 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.1509259
2019-11-02 11:28:22.567 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.3027778
2019-11-02 11:28:22.580 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.4287037
2019-11-02 11:28:22.603 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.6629629
2019-11-02 11:28:22.619 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.812963
2019-11-02 11:28:22.634 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.912037
2019-11-02 11:28:22.651 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.9601852
2019-11-02 11:28:22.668 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.9851851
2019-11-02 11:28:22.684 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.9953704
2019-11-02 11:28:22.701 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -1.9990741
2019-11-02 11:28:22.718 28806-28806/com.feng.tablayoutdemo D/fzh: view = Java, v = -2.0

2019-11-02 11:28:22.526 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.0018518518
2019-11-02 11:28:22.550 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.15092592
2019-11-02 11:28:22.567 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.30277777
2019-11-02 11:28:22.580 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.4287037
2019-11-02 11:28:22.603 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.662963
2019-11-02 11:28:22.619 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.81296295
2019-11-02 11:28:22.634 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.912037
2019-11-02 11:28:22.651 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.96018517
2019-11-02 11:28:22.668 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.9851852
2019-11-02 11:28:22.685 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.9953704
2019-11-02 11:28:22.702 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -0.9990741
2019-11-02 11:28:22.718 28806-28806/com.feng.tablayoutdemo D/fzh: view = Android, v = -1.0

2019-11-02 11:28:22.526 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.99814814
2019-11-02 11:28:22.550 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.84907407
2019-11-02 11:28:22.567 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.69722223
2019-11-02 11:28:22.580 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.5712963
2019-11-02 11:28:22.603 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.33703703
2019-11-02 11:28:22.619 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.18703704
2019-11-02 11:28:22.634 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.08796296
2019-11-02 11:28:22.651 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.039814815
2019-11-02 11:28:22.668 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.014814815
2019-11-02 11:28:22.685 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.0046296297
2019-11-02 11:28:22.702 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 9.259259E-4
2019-11-02 11:28:22.718 28806-28806/com.feng.tablayoutdemo D/fzh: view = 计算机网络, v = 0.0

可以看到,Java 页面由左边页变为左左边页,position 值则从 -1 变化到 -2;Android 页面由当前页变为左边页,position 值则从 0 变化到 -1;计算机网络页面由右边页变为当前页,position 值则从 1 变化到 0。

结果跟我的猜测是一样,说明我上面的理解是没问题的,我之后又滑动了几次,总结出 position 的值的变化规律如下:

小结 position 的变化规律

  1. 每次移动时,有三个页面的 position 值会改变,分别是当前页面、左边页面、右边页面。(如果当前页面在最左边或最右边,那就只有两个页面的 position 值改变)
  2. 页面位置和 position 值的关系:
页面位置position 值
当前页面0
左边界面-1
左左边界面-2
右边界面1
右右边界面2
  1. 对于 position 值要改变的三个(两个)界面,它的 position 值会根据页面位置的改变而改变:例如在移动过程中,某界面从当前页面变为左边页面,那么它的 position 值就会从 0 到 -1 变化。

参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值