效果图:
首先实现思路:
1.继承ViewPager.PageTransformer 重写 transformPage 方法 让每页的大小根据位置有响应的缩放;
代码如下:
public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
//自由控制缩放比例
private static final float MAX_SCALE = 1f;
private static final float MIN_SCALE = 0.8f;//0.85f
@Override
public void transformPage(@NonNull View page, float position) {
if (position <= 1) {
float scaleFactor = MIN_SCALE + (1 - Math.abs(position)) * (MAX_SCALE - MIN_SCALE);
page.setScaleX(scaleFactor);
if (position > 0) {
page.setTranslationX(-scaleFactor * 2);
} else if (position < 0) {
page.setTranslationX(scaleFactor * 2);
}
page.setScaleY(scaleFactor);
} else {
page.setScaleX(MIN_SCALE);
page.setScaleY(MIN_SCALE);
}
}
}
步骤2 就需要用父布局套上vp 再放到中间显示 ,再用父布局控制子布局超出显示:
关键参数 clipChildren
<!-- 假数据-->
<LinearLayout
android:id="@+id/ll_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipChildren="false"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:text="viewpager实现画廊效果"
android:textColor="@color/colorPrimary" />
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="200dp"
android:layout_height="300dp"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:layout_marginBottom="30dp"
android:clipChildren="false"
android:fadingEdge="none" />
</LinearLayout>
超出的布局也要响应滑动
ll_layout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mViewPager.dispatchTouchEvent(motionEvent);
}
});
有个坑,vp滑到到尽头有个动画,会导致外侧布局的clipChildren 在尽头失效
解决思路1: 假处理,设置成无限的 然后 设置到初始设置到种间显示
解决思路2:禁动画
// mViewPager.setOverScrollMode(View.OVER_SCROLL_NEVER);
ps:发版本前的时候又出现了一个问题,刷新vp里的关注按钮状态时候,PageTransformer会失效,查了几个方案 都没解决,绕路过去了,把卡片布局换成了recyleView 刷新列表的item,解决了问题