UI之ViewPager实现画廊效果

本文介绍了如何利用Android的ViewPager实现类似英语流利说广告Banner的画廊效果。通过设置ViewPager的padding、clipToPadding属性,并配合PageTransformer,实现一次显示三个Item,其中一个完整显示,其余两个缩小显示。最后通过调整动画效果,完成页面滑动的平滑过渡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

最近在学习英语,在使用英语流利说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
        }

效果如下
在这里插入图片描述
基本就是这个亚子了,项目地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值