Android引导界面设计之ParallaxViewPager视差效果

来源:互联网 发布:泰安网络广告公司 编辑:程序博客网 时间:2024/04/29 14:47

        引导界面大多都是利用ViewPager实现,通过左右滑动来展示应用程序的功能、特色、使用方式等。具体的实现也很简单,写几个要展示的xml布局文件,通过ViewPager的Adapter适配给ViewPager,下面的小圆点指示器可以用一个线性布局来容纳,选中状态可以利用drawable中的enable状态来指定相应的圆点图片,在程序中根据页面的滑动情况(onPageSelected(int position))将圆点ImageView设置setEnable状态就行了。我之前写过一个循环滚动的例子,可以看一下:自动滚动广告条。

        重点来了,如果在滚动的过程中,页面各个元素的移动速度不一样,页面切换平滑过渡,那么这样的视觉效果就会给人提别舒服的感觉,让人印象深刻。这种视觉效果往往叫做视差(Parallax)。

        具体怎么实现呢?每个元素移动速度都不一样,就需要为每个元素设置x,y和alpha的进入和推出速度的属性,所以要自定义ImageView添加这些属性,或者不自定义View直接自定义这6个属性就行了。在滑动的过程中,根据滑动的距离以及各个View的x,y,alpha的6个速度值计算出各个View实际应滑动的距离。这个大家肯定会想到利用ViewPager的PageChangeListener来监听欢动状态,在不断回调的onPageScrolled方法中进行计算,但ViewPager还有一个用来监听滑动事件的回调方法ViewPager.PageTransformer接口的transformPage(View view, float position),利用setPageTransformer来指定这个回调。transformPage方法的第一个参数是当前滑动的View。position指当前滑动状态,以屏幕左边界为原点向右画一个数轴,position也就是View的左边界距离屏幕左边界多少个身位(宽度),以向右为正。当前View在屏幕中央时position是0.0,滑动到右边不可见时position为1.0,滑动到左边不可见时为-1.0。


        由于滑动的缓冲,position小于-1.0或者大于1.0是很有可能的,所以判断并设置动画时,页面从左边离开屏幕时position<1;滑动过程中-1<=position<=1,其中[-1,0]是左边的页面,(0,1]是右边的页面;从右边离开屏幕时position>1。在页面滑动的过程中可以让View根据position的变化而变化。例如官方示例中的DepthPageTransformer:

public class DepthPageTransformer implements ViewPager.PageTransformer {    private static final float MIN_SCALE = 0.75f;    public void transformPage(View view, float position) {        int pageWidth = view.getWidth();        if (position < -1) { // [-∞,-1)            // 当前页面从左侧离开屏幕            view.setAlpha(0);        } else if (position <= 0) { // [-1,0]            //左边的页面使用ViewPager默认的过渡动画            view.setAlpha(1);            view.setTranslationX(0);            view.setScaleX(1);            view.setScaleY(1);        } else if (position <= 1) { // (0,1]            // 右边的页面缩放淡入淡出,右侧页面从右侧进入时position:1→0,右侧页面从右侧退出时position:0→1。            view.setAlpha(1 - position);            // 抵消默认的滑动过渡动画            view.setTranslationX(pageWidth * -position);            // 让页面在MIN_SCALE和1之间缩放            float scaleFactor = MIN_SCALE                    + (1 - MIN_SCALE) * (1 - Math.abs(position));            view.setScaleX(scaleFactor);            view.setScaleY(scaleFactor);        } else { // (1,+∞]            // 当前页面从右侧离开屏幕            view.setAlpha(0);        }    }}


        我也写了一下,滑动过程中让页面的每个元素按照自己的速率移动,虽然可以达到类似视差的效果,但页面之间的边界很清晰,左边页面的Views在滑动过程中会被右边页面的边界笔直切割,我这个强迫症肯定受不了。那怎么办呢?在ViewPager外面包裹一个FrameLayout帧布局也不行,还好看到了w446108264/XhsParallaxWelcome,他也是应用了prolificinteractive/ParallaxPager的思想。我们想一下,我们需要用FrameLayout让页面和元素能够平滑覆盖切换,我们还得用ViewPager的滑动特性,那就好办了,我自定义一个FrameLayout,把这些页面元素都加到这个帧布局中,再最上层覆盖一个空的ViewPager,这样既能使用到ViewPager的滑动特性又能让元素平滑覆盖切换,是不是很聪明、是不是很贱啊,^_^

        为了不被说重复制造轮子,我在其代码基础上进行了调整和优化,以适应我的需求。



0 0
原创粉丝点击