如何实现一个ViewPager,其中显示前一页和下一页,并且放大当前页。

9

我正在尝试创建一个能够在视图翻页上显示我的页面,使其具有良好的感觉和设计。我查看了这个link,它在某种程度上有所帮助,并且按照这个link进行实现,但最终出现了一些问题。首先是对于运行在API11以下(API8是我的目标)的设备,它不能正常工作或者外观不太好看。其次,我无法使焦点页面比下一个和前一个页面更大。出于设计的考虑,我希望它看起来像这样:

enter image description here

希望有人能够在这方面给我帮助,或者提供其他实现方法。


1
试试这个 http://code.google.com/p/carousel-layout-android/ :) 或者使用这个 http://code.google.com/p/android-3d-carousel-view/ - Deniz
嗨@deniz,感谢您的评论,但不确定这是否是我需要的。请看下面答案的评论。谢谢! - KaHeL
到目前为止,我尝试了第一个链接。它可以工作,但不满足我需要的感觉,而且缺乏如何使用的文档。此外,它限制了进一步定制的可能性。我会继续尝试下一个链接。 - KaHeL
1个回答

3

首先阅读这个。然后应用您自己的PageTransformer实现。可以像这样:

public class DepthPageTransformer implements ViewPager.PageTransformer {
    private static final float MIN_SCALE = 0.5f;
    private static final float MAX_SCALE = 0.8f;
    private static final float MIN_FADE = 0.2f;

    public void transformPage(View view, float position) {
        int pageWidth = view.getWidth();

        if (position < -1) {
            view.setAlpha(MIN_FADE);
        } else if (position < 0) {
            view.setAlpha(1 + position * (1 - MIN_FADE));
            view.setTranslationX(-pageWidth * MAX_SCALE * position);
            ViewCompat.setTranslationZ(view, position);
            float scaleFactor = MIN_SCALE
                    + (MAX_SCALE - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);
        } else if (position == 0) {
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(MAX_SCALE);
            ViewCompat.setTranslationZ(view, 0);
            view.setScaleY(MAX_SCALE);
        } else if (position <= 1) {
            ViewCompat.setTranslationZ(view, -position);
            view.setAlpha(1 - position * (1 - MIN_FADE));
            view.setTranslationX(pageWidth * MAX_SCALE * -position);

            float scaleFactor = MIN_SCALE
                    + (MAX_SCALE - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);
        } else {
            view.setAlpha(MIN_FADE);
        }
    }
}

你还需要控制子视图的绘制顺序,以使当前选中的视图位于顶部(仅在视图重叠时需要):
public class MyPager extends ViewPager {
    public MyPager(Context context) {
        this(context, null);
    }

    public MyPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected int getChildDrawingOrder(int childCount, int i) {
        if(i == childCount - 1) {
            return getCurrentItem();
        } else {
            return i >= getCurrentItem()? i + 1 : i;
        }
    }
}

ViewPager.setOffscreenPageLimit设置为2或更多,如果屏幕上有更多可见页面。
以下是结果: Result animation

@artkoening,你能提供这段代码的完整示例吗? - Favolas
其余的很明显:你需要一个带有MyPager和PagerAdapter的布局,就这些。 - artkoenig
谢谢,但我无法从中心获取翻译和缩放。它来自底部。 - Favolas
你知道如何在ViewPager2中实现相同的功能吗?由于ViewPager2类是final,您无法覆盖getChildDrawingOrder方法。 - Sergei Yendiyarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接