Android打造不一样的新手引导页面(二)

Android打造不一样的新手引导页面(二)


本系列主要分为两篇博客

打造不一样的新手引导页面(一)

Android打造不一样的新手引导页面(二)

关于页面导航器的,可以查看我的这一篇博客仿网易新闻的顶部导航指示器

上一篇博客主要讲解怎样自定义一个CirclePageIndicator控件

这篇博客主要讲解怎样更改ViewPager切换的效果。

首先我们先来看一下默认的ViewPager的切换效果,感觉是不是很普通,因为大多数时候我们经常没有用到ViewPager的动画切换效果 ,这种想过见多了,也就觉得平淡了

下面我们来看一下我们自己实现的ViewPager页面的 切换效果,总共有 四种不同的样式

实现原理说明

其实要实现上述的 效果非常简单,只需要以下几行代码,就搞定了。

viewpager.setPageTransformer(true, new  ViewPager.PageTransformer() {
    @Override
    public void transformPage(View page, float position) {
        // do transformation here
        }
});

Google官方关于两个参数的解释是

reverseDrawingOrder boolean: true if the supplied PageTransformer requires page views to be drawn from last to first instead of first to last.

transformer ViewPager.PageTransformer: PageTransformer that will modify each page’s animation properties

第一个布尔型参数表示的意思就是在两个页面切换产生动画效果时候是否要反转一下让下一个页面在上一个页面底下,因为ViewPager默认下一个页面是绘制在上一个页面的上面,这里一般传入true。

第二次参数才是重点,这里实现了PageTransformer接口,然后我们所有需要的动画效果都在transformPage这个接口方法里面实现,现在我们来看看这个方法。

transformPage void transformPage (View page, 
                float position)

page View: Apply the transformation to this page
position

float: Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.

下面我们借用一张图片来解释position的变化

页面切换

假设当前我们屏幕中的页面是B:
  • 那么该页面的position是1,A页面的position是-1,C页面的position是1.
  • 当我们从B页面滑到c页面的时候,B页面的变化是从0减少到-1,C页面的 变化是从1减少到0,A页面的变化是从从-1向负无穷变化。当我们切好滑动到一半的时候B页面的position是-0.5,c页面的position是0.5。
  • 当我们从B页面滑动到A页面的时候,B页面的变化是【0,1】,A页面的变化是【-1,0】,c页面的变化是从1向正无穷变化

解释完这些参数是什么意思,下面让我们来看一下我们是怎样实现的

Google的两个例子

首先我们先来看一下官方的两个例子,地址是:http://developer.android.com/training/animation/screen-slide.html

ZoomOutPageTransformer

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);
        }
    }
}

运行到上述的代码,效果图如下

从上述效果图可以看到,页面切换的时候,主要是页面大小的 变化,水平移动距离的变化以及透明度的变化,这些也可以从代码中体现回来,我们主要关心[-1,1]的时候就OK,因为在[-Infinity,-1)和(1,+Infinity]的时候是不可见的。

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

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

    // Fade the page relative to its size.
    page.setAlpha(MIN_ALPHA +
            (scaleFactor - MIN_SCALE) /
                    (1 - MIN_SCALE) * (1 - MIN_ALPHA));

} else { // (1,+Infinity]
    // This page is way off-screen to the right.
    page.setAlpha(0);
}

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) { // [-Infinity,-1)
            // This page is way off-screen to the left.
            view.setAlpha(0);

        } else if (position <= 0) { // [-1,0]
            // Use the default slide transition when moving to the left page
            view.setAlpha(1);
            view.setTranslationX(0);
            view.setScaleX(1);
            view.setScaleY(1);

        } else if (position <= 1) { // (0,1]
            // Fade the page out.
            view.setAlpha(1 - position);

            // Counteract the default slide transition
            view.setTranslationX(pageWidth * -position);

            // Scale the page down (between MIN_SCALE and 1)
            float scaleFactor = MIN_SCALE
                    + (1 - MIN_SCALE) * (1 - Math.abs(position));
            view.setScaleX(scaleFactor);
            view.setScaleY(scaleFactor);

        } else { // (1,+Infinity]
            // This page is way off-screen to the right.
            view.setAlpha(0);
        }
    }
}

运行上述代码以后,可以看到的变化是


下面来看一下我们自己实现的两个例子

看到上述图以后,仔细分析可以看到在我们滑动的时候主要是旋转角度的 变化,并且Y轴旋转中心是页面的中心点,当position<0的时候,X轴的中心是view.getWidth,当position>0的时候,x轴的中心是0,代码如下。

public class CubeOutTransformer extends BaseTransformer {

    @Override
    protected void onTransform(View view, float position) {
        view.setPivotX(position < 0f ? view.getWidth() : 0f);
        view.setPivotY(view.getHeight() * 0.5f);
        view.setRotationY(90f * position);
    }



    @Override
    public boolean isPagingEnabled() {
        return true;
    }

}

TableTransformer

public class TableTransformer extends BaseTransformer {

    private static final Matrix OFFSET_MATRIX = new Matrix();
    private static final Camera OFFSET_CAMERA = new Camera();
    private static final float[] OFFSET_TEMP_FLOAT = new float[2];
    private static final float  minScale=0.6f;

    @Override
    protected void onTransform(View view, float position) {
        final float rotation = (position < 0 ? 30f : -30f) * Math.abs(position);

        view.setTranslationX(getOffsetXForRotation(rotation, view.getWidth(), view.getHeight()));
        view.setPivotX(view.getWidth() * 0.5f);
        view.setPivotY(0);
        view.setRotationY(rotation);
        float scaleX=Math.max(1-Math.abs(position),minScale);
        view.setScaleX(scaleX);

    }

    protected static final float getOffsetXForRotation(float degrees, int width, int height) {
        OFFSET_MATRIX.reset();
        OFFSET_CAMERA.save();

        OFFSET_CAMERA.rotateY(Math.abs(degrees));
        OFFSET_CAMERA.getMatrix(OFFSET_MATRIX);
        OFFSET_CAMERA.restore();

        OFFSET_MATRIX.preTranslate(-width * 0.5f, -height * 0.5f);
        OFFSET_MATRIX.postTranslate(width * 0.5f, height * 0.5f);
        OFFSET_TEMP_FLOAT[0] = width;
        OFFSET_TEMP_FLOAT[1] = height;
        OFFSET_MATRIX.mapPoints(OFFSET_TEMP_FLOAT);
        return (width - OFFSET_TEMP_FLOAT[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
    }
}

到此我们的源码分析为止


题外话

如果各位觉得还行的话,欢迎在github上面 star或者 fork,谢谢 ,github项目地址ViewPagerTabIndicator

转载请注明原博客地址

源码下载地址:

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdutxiaoxu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值