自定義ViewPager切換動畫

前言

我們都知道項目里的廣告輪播大部分都是viewpager做的,viewpager的使用也是非常簡單的,相信大家都會用,但是大部分應用的廣告輪播都是前篇一律的普通的切換效果。我們是否有想過改變一下這個輪播的切換動畫呢。今天我們就來分析下viewpager的一個方法。沒錯了,就是實現(xiàn)ViewPager.PageTransformer這個接口,這個接口只有一個方法transformPage(View view, float position) ,通過重寫這個方法,就可以輕松地實現(xiàn)這個實現(xiàn)各種炫酷的切換動畫效果~~

正文

自己先寫了幾個效果圖,先來瞅瞅長啥樣。

image.png

哈哈,開個玩笑,來看看這些動畫吧。

廣告切換效果
翻書效果
引導圖切換效果

看到這里,大家應該就知道通過這個接口,我們可以實現(xiàn)很多好看的動畫效果了吧。

使用步驟

  • 自定義PageTransformer類,實現(xiàn)ViewPager.PageTransformer這個接口,重寫方法transformPage(View view, float position)
  • 調(diào)用ViewPagerd的setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 這個方法即可。
    可以看到,使用時非常簡單的。今天我們主要是來看看重寫PageTransforme這個類到底是怎么使用的。

自定義PageTransformer類

自定義PageTransformer類,我拿一個例子來說明一下它的做法,就拿這個廣告切換的輪播效果看看吧,


廣告切換效果
  • 首先可以看到這個viewpger是多屏顯示的,一般來說viewpager都是單屏顯示的,這里要用介紹一下clipChildren屬性。

clipchildren

含義

是否允許子View超出父View的返回,有兩個值true 、false ,默認true
使用的時候給子View和根節(jié)點View控件都設置android:clipChildren="false",那么這個子View就不會限制在父View當中

  • viewpager使用示例
<?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"
              android:gravity="center"
              android:clipChildren="false"
              android:orientation="vertical">
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="250dp"
        android:layout_height="400dp"
        android:clipChildren="false"
       ></android.support.v4.view.ViewPager>
</LinearLayout>

實現(xiàn)的效果大體是這樣的

image.png

代碼我就不貼了,自己寫寫看看~
下面講講切換效果是怎么實現(xiàn)的。

切換效果實現(xiàn)

這里主要是分析transformPage(View view, float position),我們來看看view參數(shù)和position參數(shù)
我是自己打日志看的,分析一下左滑和右滑的情況【看著效果圖實現(xiàn)】

image.png
  • 左滑【從A到B】
    這時候發(fā)現(xiàn)A的position的變化是從0-1之間變化,B的position參數(shù)是從10之間變化
  • 右滑【從C到B】
    這時候發(fā)現(xiàn)B的position的變化是從-10之間變化,C的position參數(shù)是從01之間變化。
  • 結(jié)論
    也也就是說左邊那個view的參數(shù)始終是從0和-1之間變化的,而右邊那個view的參數(shù)始終是從0到1之間變化的。小于等于-1的時候即在最左邊,大于等于1的時候即在最右邊。
  • 模板代碼如下
 if (position <= -1) {//超出最左邊,此時不可見隱藏即可
            // TODO
        } else if(position > -1 && position < 0){//左邊的view
            // TODO
        } else if (position < 1 && position >= 0) {//右邊的view
          // TODO
        } else {//超出最右邊,此時不可見隱藏即可
          // TODO
        }

知道這個變化就好辦了,來看看效果圖的變化
定義的幾個常量

 private static final float MIN_WIDTH_SCALE = 0.65f;//寬度最小縮小比例
 private static final float MIN_HEIGHT_SCALE = 0.6f;//高度最小縮小比例
 private static final float MIN_ALPHA = 0.5f;//最小透明度

接下來分析從A到B

左邊view的scaleX的變化

  • 最左邊的時候?qū)挾葹樵瓕挾鹊?.6倍【此時position的值為-1】
  • 原位置的時候?qū)挾葹樵瓕挾取敬藭rposition的值為0】

scaleX的變化函數(shù)如圖

所以可以得出左邊view的ScaleX的值得變化為
scaleX = (1 - MIN_WIDTH_SCALE) * position + 1
相應的算出
scaleY = (1 - MIN_HEIGHT_SCALE) * position + 1
alpha = 1 - MIN_ALPHA) * position + 1

右邊view的scaleX的變化

  • 原位置的時候?qū)挾葹樵瓕挾取敬藭rposition的值為1】
  • 最右邊的時候?qū)挾葹樵瓕挾鹊?.6倍【此時position的值為0】

scaleX的變化函數(shù)如圖

所以可以得出右邊view的ScaleX的值得變化為
scaleX = 1 - (1 - MIN_WIDTH_SCALE) * position
相應的算出
scaleY = 1 - (1 - MIN_HEIGHT_SCALE) * position
alpha = 1 - (1 - MIN_ALPHA) * position

完整代碼

public class ZoomOutTransformer implements ViewPager.PageTransformer {

    private static final float MIN_WIDTH_SCALE = 0.65f;//寬度最小縮小比例
    private static final float MIN_HEIGHT_SCALE = 0.6f;//高度最小縮小比例
    private static final float MIN_ALPHA = 0.5f;//最小透明度

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

        if (position <= -1) {//超出最左邊
            view.setAlpha(MIN_ALPHA);
            view.setScaleX(MIN_WIDTH_SCALE);
            view.setScaleY(MIN_HEIGHT_SCALE);
        } else if(position > -1 && position < 0){//左邊view
            //float fraction = position + 1;
            view.setScaleX((1 - MIN_WIDTH_SCALE) * position + 1);
            view.setScaleY((1 - MIN_HEIGHT_SCALE) * position + 1);
            view.setAlpha((1 - MIN_ALPHA) * position + 1);
        } else if (position < 1 && position >= 0) {//右邊view
            view.setAlpha(1);
            view.setScaleX(1 - (1 - MIN_WIDTH_SCALE) * position);
            view.setScaleY(1 - (1 - MIN_HEIGHT_SCALE) * position);
            view.setAlpha(1 - (1 - MIN_ALPHA) * position);
        } else {//超出最右邊
            view.setAlpha(MIN_ALPHA);
            view.setScaleX(MIN_WIDTH_SCALE);
            view.setScaleY(MIN_HEIGHT_SCALE);
        }
    }
}

結(jié)語

使用是不是相當簡單呀,通過這個可以做出很多動畫效果,來看看結(jié)合這個實現(xiàn)的App廣告輪播吧


今天就寫到這里了,enjoy it~
源代碼

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 實現(xiàn)基礎的ViewPager### 1.主布局文件activity_main.xml,一個用于放ViewPager...
    陌上疏影涼閱讀 2,270評論 4 10
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,324評論 25 708
  • Scrapy簡介 Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應用框架。 Scrapy入門請看官方文...
    蠻三刀醬閱讀 1,057評論 0 3
  • 這個世界上有一種人被全世界痛恨著,不是獨裁的軍政府,也不是窮兇極惡的恐怖分子。而是一種變異的人類,這種人類大致分為...
    楊光宇閱讀 431評論 0 0
  • 昨天晚上,吃過晚飯,兒子就說要出去鍛煉,我跟蹤發(fā)現(xiàn)孩子每天晚上不學習是去跟同學出去到一個西單旁邊的新一代八樓的尤拉...
    崔海宏閱讀 350評論 1 6

友情鏈接更多精彩內(nèi)容