PageTransformer用于处理“居中”页面

时间:2014-01-07 01:09:47

标签: android android-viewpager android-animation

我有一个显示3个不同页面的ViewPager。我想通过使用Google的一个示例中的ZoomOutPageTransformer来为寻呼机设置动画:

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
    private static float MIN_SCALE = 0.85f;
    private static float MIN_ALPHA = 0.5f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();
        int pageHeight = view.getHeight();
        int pageOffset = 1; //one page offset

        if (position < -1) { // [-Infinity,-2)
            // 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);
        }
    }

我添加了变量“pageOffset”。我现在想要的是不是第一页的动画,而是第二页(居中)页面。所以我必须将整个动画向右移动一步。然后,居中的页面将“更大”,并且比其他页面更明显。

但是我无法做到这一点。我试图将位置改为position+offset但没有成功。我应该在这个片段中做些什么来获得我想要的结果?

编辑:我认为这样可行 - 但是,它不会:

public void transformPage(View view, float position) {
  int pageWidth = view.getWidth();
  int pageHeight = view.getHeight();
  int pageOffset = 1; //one page offset

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

} else if (position - pageOffset <= 1) { // [-1,1]
    // Modify the default slide transition to shrink the page as well
    float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position - pageOffset));
    float vertMargin = pageHeight * (1 - scaleFactor) / 2;
    float horzMargin = pageWidth * (1 - scaleFactor) / 2;
    if (position - pageOffset < 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);
}

}

1 个答案:

答案 0 :(得分:3)

我不完全确定您的意图,因为pageOffset设置为1并且从未更新过。也就是说,也许对我对PageTransformer的理解的解释将会有所启发:

   if (mPageTransformer != null) {
        final int scrollX = getScrollX();
        final int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.isDecor) continue;

            final float transformPos = (float) (child.getLeft() - scrollX) / getClientWidth();
            mPageTransformer.transformPage(child, transformPos);
        }
    }

这是从ViewPageronPageScrolled方法获取的代码段。在transformPage方法中,您应该使用position参数来确定要应用的ZoomOutPageTransformer中显示的动画:

if (position < -1) // This view is leftward beyond visibility.
else if (position <= 1) // This is our center view being scrolled into visibility.
else // This view is rightward beyond visibility.

另一个例子:

    @Override
    public void transformPage(View page, float position) {
        if (position >= 0) {
            page.setAlpha(Math.abs(Math.abs(position) - 1));
        }
    }

根据具体情况,此方法可能最多被调用三次。让我们看看我们有三个视图并从最左边(0)滚动到中间(1)的情况。如果我们处于转换的中途,Math.abs(Math.abs(position) - 1)对于两个视图都将为0.5 | | 0.5 | - 1 | = 0.5。这样,我们会对两个视图应用50%的不透明度。