背景
最近在學習英語,在使用英語流利說App的時候看到一個廣告banner,如下圖:
怎麼實現這種效果呢?用ViewPager實現!
實現
從圖中可以看出,一次顯示三個Item,一個完整的,兩個冒點頭並且相較於完整的高度較小,我們知道平時VIewPager是每個Item佔一整頁的,怎麼實現一頁顯示三個呢?從ViewPager的onMeasure()與onLayout()我們知道Item的寬高和佈局受到ViewPager的Padding影響。相關代碼如下:
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
....
// Children are just made to fill our space.
int childWidthSize = measuredWidth - getPaddingLeft() - getPaddingRight();
int childHeightSize = getMeasuredHeight() - getPaddingTop() - getPaddingBottom();
......
for (int i = 0; i < size; ++i) {
......
int widthSize = childWidthSize;
int heightSize = childHeightSize;
...
final int widthSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
final int heightSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
child.measure(widthSpec, heightSpec);
}
}
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
.....
for (int i = 0; i < count; i++) {
int childLeft = 0;
...
childLeft = paddingLeft;
...
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(),
childTop + child.getMeasuredHeight());
}
}
Ok,我們給ViewPager添加padding,看看效果:
emm,Item的大小確實變小了,但是說好的顯示三個呢???我們滑動一下看看是啥樣子
發現兩個Item是相連的,但是隻顯示一個出來,這是爲什麼呢?這裏涉及到ViewGroup的一個屬性clipTopadding,它做了什麼呢,看看代碼
ViewGroup.class
protected void dispatchDraw(Canvas canvas) {
...
final boolean clipToPadding = (flags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK;
if (clipToPadding) {
clipSaveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
canvas.clipRect(mScrollX + mPaddingLeft, mScrollY + mPaddingTop,
mScrollX + mRight - mLeft - mPaddingRight,
mScrollY + mBottom - mTop - mPaddingBottom);
}
....
}
文字太過蒼白,看圖,它的作用大致如下
就是clipToPadding=true時,ViewGroup在繪製子View的時候裁剪了下,OK,現在我們把clipToPadding設爲false,效果如下
這下都顯示出來了吧,接下來我們給ViewPager設置一個PagerMargin,設置爲padding的一半,看看效果
有點那個樣子了啊,接下來就是設置pager轉變過程中的動畫了,就是VIewPager的setPageTransformer()方法,這裏有個參數position,它的值反映了pager的轉換過程,0代表了pager位於中間的顯示位置,-1是在左側,1在右側,我們可以通過這個值來寫一個動畫,這裏動畫我設置了個簡單的,就是改變pager的ScaleY的值,positon爲0,scaleY=1,position=-1或position=1,scaleY=0.95,二次方程,求得,y=-xx0.05+1,代碼設置如下
vp_gallery.setPageTransformer(false){
page, position ->
page.scaleY=-position*position*0.05f+1f
}
效果如下
基本就是這個亞子了,項目地址