ViewPager系列之 仿魅族应用的广告BannerView

来源:互联网 发布:京东剑客软件 编辑:程序博客网 时间:2024/05/16 04:37

转自:http://www.jianshu.com/p/653680cfe877#
目的:添加自己的理解和注释。
主要改动:展示多页的更深解释、动画效果的优化。
1 . ViewPager展示多页
要让ViewPager页面展示多页的内容,就要用到ViewGroup的一个强大的属性。这个属性虽然强大,但是也不常用,可能有些小伙伴不知道(之前我也没用过…),那就是clipChildren属性。这个属性有什么作用呢,我们看一下它的文档介绍:

/**     * By default, children are clipped to their bounds before drawing. This     * allows view groups to override this behavior for animations, etc.     *     * @param clipChildren true to clip children to their bounds,     *        false otherwise     * @attr ref android.R.styleable#ViewGroup_clipChildren     */

clipChildren: 默认值为true, 子View 的大小只能在父View规定的范围之内,比如父View的高为50,子View的高为60 ,那么多处的部分就会被裁剪。如果我们设置这个值为false的话,那么多处的部分就不会被裁剪了。

clipChildren的意思:是否限制子View在其范围内,我们将其值设置为false后那么当子控件的高度高于父控件时也会完全显示,而不会被压缩,ViewPager是一组连续的图片,我们设置了false,其实父控件也不能控制ViewPager的大小了。

这里我们就可以利用这个属性来实现了这个效果了,我们设置ViewPager的父布局的clipChildren为false。然后设置ViewPager 左右一定的边距,那么左右就空出了一定的区域,利用clipChildren 属性,就能让前后页面的部分显示在当前页了。布局如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:clipChildren="false"    android:orientation="vertical"    >   <android.support.v4.view.ViewPager       android:id="@+id/view_pager"       android:layout_width="match_parent"       android:layout_height="200dp"       android:layout_marginLeft="30dp"       android:layout_marginRight="30dp"       /></LinearLayout>

这样就能实现ViewPager 展示前后页面的部分内容。
2 . 自定义ViewPager.PageTransformer动画
上面实现了ViewPager当前页面显示前后页的部分内容,但是从最开始魅族的Banner效果我们可以看出,滑动的时候是有 一个放大缩小的动画的。左右显示的部分有一定比例的缩小。这就要用到ViewPager.PageTransformer了。

ViewPager.PageTransformer 干什么的呢?ViewPager.PageTransformer 是用来做ViewPager切换动画的,它是一个接口,里面只有一个方法transformPage。

 public interface PageTransformer {        /**         * Apply a property transformation to the given page.         *         * @param page Apply the transformation to this page         * @param position 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.         */        void transformPage(View page, float position);    }

虽然只有一个方法,但是它很强大,它能反映出在ViewPager滑动过程中,各个View的位置变化。我们拿到了这些位置变化,就能在这个过程中对View做各种各样的动画了。

要自定义动画,我们就来需要知道positon这个值的变化区间。从官方给的ViewPager的两个示例我们知道,position的变换有三个区间,[-Infinity,-1),[-1,1],(1.Infinity)。
[-Infinity,-1):已经在屏幕之外,看不到了
(1.Infinity): 已经在屏幕之外,看不到了。
[-1,1]: 这个区间是我门操作View动画的重点区间。
我们来看一下官方对于position的解释:

官方的解释:The position parameter indicates where a given page is located relative to the center of the screen. It is a dynamic property that changes as the user scrolls through the pages. When a page fills the screen, its position value is 0. When a page is drawn just off the right side of the screen, its position value is 1. If the user scrolls halfway between pages one and two, page one has a position of -0.5 and page two has a position of 0.5.

根据解释,也就是说当前停留的页面的位置为 0,右边屏幕之外绘制的这个页面位置为 1。那么,A 页面滑到 B 页面有 2 种情况:第一种:左边划出屏幕,那么 A:0 -> -1,B :1 -> 0。第二种:右边划出屏幕,A:0->1, B :-1-> 0

了解了这个方法的变化后,我们就来自定义我们的切换动画,这里很简单,我们只需要一个scale动画。代码如下:

public class CustomTransformer implements ViewPager.PageTransformer {    private static final float MIN_SCALE = 0.9F;    @Override    public void transformPage(View page, float position) {        Log.e("xsr", "position = " + position + ", page = " + page);        if (position <= -1) {            page.setScaleY(MIN_SCALE);        } else if (position < 1 && position > -1) {            // position会显示ViewPager里面的所有的位置。这些位置都是相对于中间(0)位置的。最中间是0,往右:1,2,3。。。往左:-1,-2,-3。。。相对位置越靠近中间(0),数值越小。相当于就是-1到0到1之间无穷的小数。所以我们直接取到这个位置的绝对值,然后乘以0.1f得到缩小的距离比例。然后再用1减去,得到最终的比例。            float scale = 1 - Math.abs(position) * 0.1f;            Log.e("xsr", "scale = " + scale);            page.setScaleY(scale);            /*page.setScaleX(scale);            if(position<0){                page.setTranslationX(width * (1 - scale) /2);            }else{                page.setTranslationX(-width * (1 - scale) /2);            }*/        } else {            page.setScaleY(MIN_SCALE);        }    }}

到此,我们仿魅族Banner的静态效果就实现了。接下来我们就要让Banner动起来,实现无限轮播效果。

阅读全文
0 0
原创粉丝点击