前言
我們都知道項(xiàng)目里的廣告輪播大部分都是viewpager做的,viewpager的使用也是非常簡單的乾颁,相信大家都會(huì)用触菜,但是大部分應(yīng)用的廣告輪播都是前篇一律的普通的切換效果影晓。我們是否有想過改變一下這個(gè)輪播的切換動(dòng)畫呢闸天。今天我們就來分析下viewpager的一個(gè)方法。沒錯(cuò)了扔亥,就是實(shí)現(xiàn)ViewPager.PageTransformer這個(gè)接口场躯,這個(gè)接口只有一個(gè)方法transformPage(View view, float position) ,通過重寫這個(gè)方法旅挤,就可以輕松地實(shí)現(xiàn)這個(gè)實(shí)現(xiàn)各種炫酷的切換動(dòng)畫效果~~
正文
自己先寫了幾個(gè)效果圖踢关,先來瞅瞅長啥樣。
哈哈粘茄,開個(gè)玩笑耘成,來看看這些動(dòng)畫吧。
看到這里驹闰,大家應(yīng)該就知道通過這個(gè)接口,我們可以實(shí)現(xiàn)很多好看的動(dòng)畫效果了吧撒会。
使用步驟
- 自定義PageTransformer類嘹朗,實(shí)現(xiàn)ViewPager.PageTransformer這個(gè)接口,重寫方法transformPage(View view, float position)
- 調(diào)用ViewPagerd的setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) 這個(gè)方法即可诵肛。
可以看到,使用時(shí)非常簡單的屹培。今天我們主要是來看看重寫PageTransforme這個(gè)類到底是怎么使用的。
自定義PageTransformer類
自定義PageTransformer類怔檩,我拿一個(gè)例子來說明一下它的做法褪秀,就拿這個(gè)廣告切換的輪播效果看看吧,
- 首先可以看到這個(gè)viewpger是多屏顯示的薛训,一般來說viewpager都是單屏顯示的媒吗,這里要用介紹一下clipChildren屬性。
clipchildren
含義
是否允許子View超出父View的返回乙埃,有兩個(gè)值true 闸英、false ,默認(rèn)true
使用的時(shí)候給子View和根節(jié)點(diǎn)View控件都設(shè)置android:clipChildren="false"介袜,那么這個(gè)子View就不會(huì)限制在父View當(dāng)中
- 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>
實(shí)現(xiàn)的效果大體是這樣的
代碼我就不貼了甫何,自己寫寫看看~
下面講講切換效果是怎么實(shí)現(xiàn)的。
切換效果實(shí)現(xiàn)
這里主要是分析transformPage(View view, float position)遇伞,我們來看看view參數(shù)和position參數(shù)
我是自己打日志看的辙喂,分析一下左滑和右滑的情況【看著效果圖實(shí)現(xiàn)】
-
左滑【從A到B】
這時(shí)候發(fā)現(xiàn)A的position的變化是從0 到 -1之間變化,B的position參數(shù)是從1到 0之間變化 -
右滑【從C到B】
這時(shí)候發(fā)現(xiàn)B的position的變化是從-1 到 0之間變化,C的position參數(shù)是從0到 1之間變化巍耗。 -
結(jié)論
也也就是說左邊那個(gè)view的參數(shù)始終是從0和-1之間變化的秋麸,而右邊那個(gè)view的參數(shù)始終是從0到1之間變化的。小于等于-1的時(shí)候即在最左邊芍锦,大于等于1的時(shí)候即在最右邊竹勉。 - 模板代碼如下
if (position <= -1) {//超出最左邊,此時(shí)不可見隱藏即可
// TODO
} else if(position > -1 && position < 0){//左邊的view
// TODO
} else if (position < 1 && position >= 0) {//右邊的view
// TODO
} else {//超出最右邊娄琉,此時(shí)不可見隱藏即可
// TODO
}
知道這個(gè)變化就好辦了次乓,來看看效果圖的變化
定義的幾個(gè)常量
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的變化
- 最左邊的時(shí)候?qū)挾葹樵瓕挾鹊?.6倍【此時(shí)position的值為-1】
- 原位置的時(shí)候?qū)挾葹樵瓕挾取敬藭r(shí)position的值為0】
所以可以得出左邊view的ScaleX的值得變化為
scaleX = (1 - MIN_WIDTH_SCALE) * position + 1
相應(yīng)的算出
scaleY = (1 - MIN_HEIGHT_SCALE) * position + 1
alpha = 1 - MIN_ALPHA) * position + 1
右邊view的scaleX的變化
- 原位置的時(shí)候?qū)挾葹樵瓕挾取敬藭r(shí)position的值為1】
- 最右邊的時(shí)候?qū)挾葹樵瓕挾鹊?.6倍【此時(shí)position的值為0】
所以可以得出右邊view的ScaleX的值得變化為
scaleX = 1 - (1 - MIN_WIDTH_SCALE) * position
相應(yīng)的算出
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é)語
使用是不是相當(dāng)簡單呀,通過這個(gè)可以做出很多動(dòng)畫效果孽水,來看看結(jié)合這個(gè)實(shí)現(xiàn)的App廣告輪播吧
今天就寫到這里了票腰,enjoy it~
源代碼