向后兼容的PageTransformer

时间:2013-04-02 15:13:05

标签: android android-viewpager android-animation nineoldandroids

我正在尝试为ViewPager中的项目设置动画,而PageTransformer符合要求。我希望它向后兼容Android 2.2所以我使用的是支持v4库。然而...

  

由于属性动画仅在Android 3.0和转发时受支持,因此在>上设置PageTransformer。早期平台版本的ViewPager将被忽略。

因此PageTransformer不适用于旧版本

我正在使用Jake Wharton's NineOldAndroids库,所以我可以使用该API,但我不确定如何为ViewPager做动画。

我怎么能这样做?

2 个答案:

答案 0 :(得分:8)

您需要使用PageTransformer包装器实现AnimatorProxy以在视图上设置转换属性。

然后,最难的部分是ViewPager会忽略较低API版本中的PageTransformer。因此,您需要修改ViewPager本身以使用PageTransformer

我有forked version of the support library on GitHub允许这个以及使用NineOldAndroids动画师进行自定义片段转换。使用animator-transition分支。它是一个maven项目,因此您可以从v4子目录构建它。

public class ZoomOutPageTransformer implements 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();

        AnimatorProxy proxy = AnimatorProxy.wrap(view);

        if (position < -1) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            proxy.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) {
                proxy.setTranslationX(horzMargin - vertMargin / 2);
            } else {
                proxy.setTranslationX(-horzMargin + vertMargin / 2);
            }

            // Scale the page down (between MIN_SCALE and 1)
            proxy.setScaleX(scaleFactor);
            proxy.setScaleY(scaleFactor);

            // Fade the page relative to its size.
            proxy.setAlpha(MIN_ALPHA +
                (scaleFactor - MIN_SCALE) /
                (1 - MIN_SCALE) * (1 - MIN_ALPHA));
        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            proxy.setAlpha(0);
        }
    }
}

答案 1 :(得分:3)

正如@ mark.kedzierski所说,从here复制了ViewPager类并删除了该版本的if语句(请参阅下面的内容)并将其命名为TransformableViewPager

public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) {
    if (Build.VERSION.SDK_INT >= 11) {
        final boolean hasTransformer = transformer != null;
        final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
        mPageTransformer = transformer;
        setChildrenDrawingOrderEnabledCompat(hasTransformer);
        if (hasTransformer) {
            mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
        } else {
            mDrawingOrder = DRAW_ORDER_DEFAULT;
        }
        if (needsPopulate) populate();
    }
}

我还必须将所有PageTransformer更改为ViewPager.PageTransformer。然后在这样的自定义PageTranformer中进行转换,

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB){
    // > 11 version
    view.setAlpha(0);
}
else
{
    // Nine Old Androids version
    ViewHelper.setAlpha(view, 0);
 }

也可以使用Ithink代理,因此您不必编写版本检查。这甚至适用于2.2