在滑动ViewPager时查看翻译

pul*_*ion 14 android android-animation android-viewpager

我正在阅读一个关于自定义ViewPager滑动页面动画的示例,该动画需要将页面(View)转换为一定量.这个例子来自文档.具体来说,它是关于一个被调用的实现ZoomOutPageTransformer,可以在一个ViewPager直通setPageTransformer()上设置以自定义页面的滑动方式(在其中包含缩放动画).

这是最终结果应该是这样的:

在此输入图像描述

现在,他们描述了他们将如何做到这一点:

在您的实现中transformPage(),您可以通过根据屏幕上页面的位置确定需要转换哪些页面来创建自定义幻灯片动画,该位置是从方法的position参数获得的transformPage().

position参数指示给定页面相对于屏幕中心的位置.它是一个动态属性,随着用户滚动页面而变化.当页面填满屏幕时,其position值为0.当页面刚刚从屏幕右侧绘制时,其position值为1.如果用户在第1页和第2页之间滚动,则第1页的position值为-0.5且第二页有position0.5.基于在position屏幕上的页面,你可以通过与方法,如设置页面属性创建自定义幻灯片动画setAlpha(),setTranslationX()setScaleY().

这是PageTransformer他们提供的实施:

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题:

我无法理解这句话,

view.setTranslationX(horzMargin - vertMargin / 2);
Run Code Online (Sandbox Code Playgroud)

我的理解是position参数的值1.0 等于覆盖屏幕宽度,即w.因此,如果页面的中心移动了x个单位,position那么以像素/ dp表示的翻译将是w*x.但他们正在使用一些保证金计算来计算翻译金额.

任何人都可以解释他们如何进行这种计算以及我的计算会出现什么问题?

Gar*_*y99 0

当我重新阅读您的问题和这个答案时,我不确定我是否真正解决了您的问题。我认为这可能会有所帮助,所以我将其发布。

根据this,position=0 表示该页面位于前面且居中(对于本例,为全屏)。我们只关心位置在-1到+1范围内的页面,否则它离视图太远而无法关心。您可以在第一个和最后一个条件中看到这一点,其中 alpha 设置为 0,使视图完全透明。

我无法理解该声明,

view.setTranslationX(horzMargin - vertMargin / 2);

当我查看它时,我也没有看到这部分代码有多大价值。由于边距是根据scaleFactor 计算的,并且限制在0.85 - 1.0 之间,因此它不会对过渡的外观产生太大影响。我确信比我更有设计眼光的人不会同意。不过,我删除了这部分代码作为实验。

        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);
        }
Run Code Online (Sandbox Code Playgroud)

虽然如果我仔细观察的话,我可以看到根据 TranslationX 设置的细微差别,但在随意使用时我永远不会注意到。通过将 MIN_SCALE 设置为 0.5(或更小)可以看到更多差异。

我的计算会有什么问题?

只要您将其限制为像当前代码那样的小结果,可能就没有什么。请记住,ViewPager 类是动画的主要控制器,而不是setTranslationX().