ViewPager动画之三个item的实现

很多项目中都会有分页切换的部分,而这个需求大家大多会使用ViewPager去实现,ViewPager是V4包里的一个官方控件,帮我们处理好了页面切换和页面预加载等逻辑,使用起来简单方便,并且给我们提供了一个默认的切换动画,尽管看起来不怎么华丽;

然后公司的UI设计师看到后就说了,这动画看起来实在是平淡如水呀,得加点情怀进去,然后给了个如下的样式:

Page页不是一成不变的滑入滑出,而是缩放着滑动,这该如何下手呢,突然间灵光闪现:监听ViewPager的滑动切换事件,使用OnPageChangeListener接口里的onPageScrolled方法来控制内容view的形状动画;不错,这个方法确实也可以实现切换动画,但其实实现起来比较XX,众所周知ViewPager在一般情况下有当前页,当前页前一页和后一页,自定义ViewPager动画时不仅要定义滑出页的动画,也要定义滑入页的动画,这样一来如果有个专门的回调方法来让我们获取到ViewPager这几个关键页的滑动偏移量的具体值就爽了,这时大家就发现了在ViewPager类里有个方法叫setPageTransformer(),这个方法就是android在3.0开始支持自定义ViewPager切换动画时暴露的接口PageTransformer,这个接口里只需要实现一个方法transformPage(View
page, float position),通过对position的判断就可以实现很多动画效果。

当ViewPager滑动切换时,所有存活的Page页都会执行transformPage方法,下面解释下position值的意义:

1.当前页处于正中间时,当前页A的position=0,如图1所示;

2.假设向左滑动到一半,此时当前页能看到右边的一半,当前页的右边一页能看到左边的一半,如图2所示,这时候刚才的当前页A的position会从0变成-0.5f(假设完全准确的滑动到一半),当前页A的右边一页B的position会从1变成0.5f;当B页完全显示在中间时,B页就会成为图1中A页的状态,position变为0,而A页的position会变成-1;

分析完position后先来把这个所谓有情怀的效果给实现了吧,先从效果图中找出动画的特点:和默认的ViewPager动画相比,这个动画滑出的Page都是X轴方向渐渐缩小,滑入的Page都是X轴方向渐渐放大,产生一种视差效果;

a.比个手指向右边滑动时的如吧,当前页position渐渐从0变成1,page需要让它渐渐变小,那么可以这样实现:

mViewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                Log.e("TAG", "imageview" + page.getTag() + "------:" + position);
                if (position > 0 && position <= 1) {
                    page.setPivotX(0);
                    page.setScaleX(1 - position);
                }
            }
        });

page.setPivotX(0) 是为了让相邻两页在滑动时紧紧粘连在一起,可以去掉这行看看去掉后的效果,个人感觉挺不自在的,page.setScaleX(1-
position) 就是设置滑出页的缩放值从1渐渐变成0.

那么当前页的左边一页position就会从-1渐渐变成0,page需要让它渐渐变大,那么可以这样实现:

mViewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                if (position <= 0 && position >= -1) {
                    page.setPivotX(page.getWidth());
                    page.setScaleX(1 + position);
                }
            }
        });

同理,page.setPivotX(page.getWidth()); 还是为了让相邻两页在滑动时紧紧粘连在一起,page.setScaleX(1+
position); 就是设置滑入页渐渐变大。

那么完整的就是

mViewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                if (position > 0 && position <= 1) {
                    page.setPivotX(0);
                    page.setScaleX(1 - position);
                } else if (position <= 0 && position >= -1) {
                    page.setPivotX(page.getWidth());
                    page.setScaleX(1 + position);
                }
            }
        });

OK,一个普通的ViewPager加上这段代码,上面的情怀动画就有了。

那哥们就说了:这我会做,也太简单了,我可收藏了好多动画呢,都不用自己写...

大兄弟,别着急,为了不让你白来,我再给个你收藏下;

UI设计师看了后挺满意的,以为做起来特别复杂,但是另一个项目里只有情怀还不够,还要看着稍时尚一点,要给人一种既欢喜又悲伤、既古典又现代、既可爱又严肃的感觉,对(大腿一拍),就这个feel~

然后就拿来了上面这个效果,细想下能发现,这依然可以使用上文提到到的PageTransformer接口来实现;

特点:1.一页显示三个Item,看到这里那哥们就坐不住了,你这不坑爹么,我的ViewPager都是一页一个Item的,你当我那是Gallery啊!

2.当前页左右两边的Page要比当前页的尺寸小一点,让用户一看就感觉中间的这个最大的页就是当前页,并且让用户知道,两边还是有内容的。

OK,这就是两个主要特点了,下面考虑实现过程:

1.让ViewPager一页显示三个Item;

2.ViewPager滑动时,自定义切换动画,让当前页两边的Page的Y轴方向尺寸比当前页小一定的高度;

跟着上面准备的顺序来,先实现一页显示三个item,这个很简单,在ViewPager的父布局里加入一条属性android:clipChildren="false",意思是让子控件不局限于自己的内部,然后设置下ViewPager的margin值,距离左右一段距离,用来显示当前页左右两边的Page;

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#F4F4F4"
    android:clipChildren="false"
    android:orientation="vertical">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        android:src="@mipmap/d" />

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="10dp"
        android:layout_marginLeft="50dp"
        android:layout_marginRight="50dp"
        android:layout_marginTop="30dp"
        />
</LinearLayout>

然后在代码还需要设置下两个Page之间的距离,不然是粘在一起的,给不了用户一种既欢喜又悲伤的感觉,调用mViewPager.setPageMargin() 方法即可设置;

这样一来,一页显示三个Item的需求就实现了;

接着就要实现当前Item两边的Item要比当前Item矮一点的效果了,先来分析下情况:

1.当前页滑动到左边,position从0渐变到-1;当前页滑动到右边,position从0渐变到1;

2.随着position的变化,page页View的高度要跟着变化,需要注意的是,高度和position并不是等量渐变的,例如手指向右滑动时,position从0渐变到1,View的高度要从1渐变到0.8(scale值,假设UI要求当前页两边的高度是当前页高度的80%),那么图像大概是这样的

看到了上面的函数图,那哥们迷之一笑,摇头晃脑(刚摇了半圈),“这是初中学...”

这时旁边清洁的老大娘也看到了,“哎,这个我知道,这不是你们初中学的那叫啥玩意儿来着?对对,二次函数”。

好吧,这个高度的scale值可以用上图所示类型的公式来得到,ax2+bx+c=y,似曾相识燕归来呀这公式;可是这个还需要通过三个点先计算出abc的值,有点烦;

为了方便,我们可以定义一个值从0渐变到0.2,然后用1减去它就得到1到0.8的渐变值了,把图变成这样

这下方便多了,y=ax2,结果为y=0.2x2;

然后代码就可以写成这样了

    private void initView() {
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
        mViewPager.setOffscreenPageLimit(3);
        mViewPager.setPageMargin(50);
        mViewPager.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(View page, float position) {
                float v = Math.abs(position);
                float v1 = (float) (0.2 * (v * v));
                page.setScaleY(1 - v1);
            }
        });
    }

Math.abs(position); 是因为两边都要执行这个渐变;

OK,上面的效果就出现了!

时间: 2024-10-04 06:09:38

ViewPager动画之三个item的实现的相关文章

CSS 实现加载动画之三-钢琴按键

原文:CSS 实现加载动画之三-钢琴按键 今天做的这个动画实现也是非常简单,简单数几行代码就可以搞定.给这个动画取了个优雅的名字--钢琴按键,也实在是想不出什么更形象的名字了.废话不多说,直接上图. 1. 先看gif图 2. 代码实现思路 2.1 定义五个方块的元素. 2.2 对方块元素使用动画,延时改变透明度. 3. 主要使用的技术 主要用到了animation动画 @-webkit-keyframes load{ 0%{opacity:1;} 100%{opacity:0;}}.m-load

android:ViewPager动画总结

设置动画的方案: 我们可以使用ViewPager的setPageTransformer方法,为ViewPager设置动画.以下是几种常见动画的演示及效果: 1.CubeInTransformer 2.CubeOutTransformer 2 3.FlipHorizontalTransformer 4.RotateUpTransformer 5.ZoomOutSlideTransformer 6.TabletTransformer 更多ViewPager的动画Demo请参见源代码: https:/

ViewPager动画详解

GitHub:lightSky 微博:    light_sky, 即时分享最新技术,欢迎关注 前言 前两天看到鲍永章分享的Great animations with PageTransformer以及农民伯伯分享的Create ViewPager transitions 文章,都是通过ViewPager来实现酷炫的动画,而现在的App中ViewPager的动画使用也非常的广泛.正好最近一直研究动画,那么就趁热打铁,分析一下相关的开源库吧.本篇文章介绍的ViewPager动画,可以分为两类,第一

使用ViewPager动画来做出不一样的引导页

就算Google从很早开始就自带了设置引导页动画的接口,但是就我目前看来市面上使用引导页动画的还是很少的,也不知道是为什么,一想到Material Design的使用率也这么少表示很心塞. 首先来看看市面上千篇一律的引导页效果,诺: 很单调对不对,你们没看吐我都看吐了,再看一份加了引导页动画效果的: 有没有瞬间耳目一新的感觉,下面就谈谈如何做出这样的引导页动画. 其实从Android 3.0也就是API 11开始Android就自带了一个PageTransformer接口用来实现ViewPage

ViewPager动画切换

1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 tools:c

动画 -- ListView列表item逐个出来(从无到有)

1 import android.app.ListActivity; 2 import android.os.Bundle; 3 import android.widget.ArrayAdapter; 4 5 public class MainActivity extends ListActivity { 6 private ArrayAdapter<String> adapter; 7 @Override 8 protected void onCreate(Bundle savedInsta

Android ViewPager 动画效果

package com.example.jaazy; import java.util.ArrayList; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; /** * Create by LanYan on 2014.04.24 * This is a ad

VIewPager显示多个Item

一直以来想搞明白这个不完全的VIewPager是怎么做到的,有幸看到这片篇文章

ViewPager 动画效果getett

package com.example.jaazy; import java.util.ArrayList; import android.support.v4.view.PagerAdapter; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; /** * Create by LanYan on 2014.04.24 * This is a ad