此篇为ViewPager2的拓展篇,具体可查看ViewPager2的使用
ViewPager2自定义动画的核心是使用PageTransformer来实现,他是ViewPager2中的一个接口
原理
要显示非默认屏幕滑动动画,请实现 ViewPager2.PageTransformer 接口并将其提供给 ViewPager2 对象。该接口只会公开一个方法 transformPage()。在屏幕切换的每个点,系统会针对每个可见页面(通常只有一个可见页面)和刚刚离开屏幕的相邻页面调用此方法。 例如,如果第 3 页可见且用户拖向第 4 页,则在手势的每个步骤,会针对第 2 页、第 3 页和第 4 页调用 transformPage()。
然后在您的 transformPage() 实现中,您可以根据页面在屏幕上的位置确定需要切换哪些页面,从而创建自定义滑动动画。页面位置取自 transformPage() 方法的 position 参数。
position 参数表示指定页面相对于屏幕中心的位置。 此参数是一个动态属性,会随着用户滚动浏览一系列页面而变化。当页面填满整个屏幕时,其位置值为 0。 当页面刚刚离开屏幕右侧时,其位置值为 1。如果用户在第一页和第二页之间滚动到一半,则第一页的位置为 -0.5,第二页的位置为 0.5。根据页面在屏幕上的位置,您可以使用 setAlpha()、setTranslationX() 或 setScaleY() 之类的方法设置页面属性,从而创建自定义滑动动画。
例:创建页面缩小动画,命名为ZoomOutPageTransformer
public class ZoomOutPageTransformer implements ViewPager2.PageTransformer {
private static final float MIN_SCALE = 0.85f;
private static final float MIN_ALPHA = 0.5f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
int pageHeight = view.getHeight();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
} else if (position <= 1) { // [-1,1]
// Modify the default slide transition to shrink the page as well
float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position));
float vertMargin = pageHeight * (1 - scaleFactor) / 2;
float horzMargin = pageWidth * (1 - scaleFactor) / 2;
if (position < 0) {
view.setTranslationX(horzMargin - vertMargin / 2);
} else {
view.setTranslationX(-horzMargin + vertMargin / 2);
}
// Scale the page down (between MIN_SCALE and 1)
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
// Fade the page relative to its size.
view.setAlpha(MIN_ALPHA +
(scaleFactor - MIN_SCALE) /
(1 - MIN_SCALE) * (1 - MIN_ALPHA));
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}
调用:
ViewPager2 mPager = findViewById(R.id.pager);
...
mPager.setPageTransformer(new ZoomOutPageTransformer());
效果图(录制来自谷歌官网)
在深度动画期间,默认动画(屏幕滑动)仍然会发生,因此您必须使用负 X 平移来抵消屏幕滑动。 例如:
view.setTranslationX(-1 * view.getWidth() * position);
以下示例展示了如何抵消可运行的页面转换器中的默认屏幕滑动动画:
public class DepthPageTransformer implements ViewPager2.PageTransformer {
private static final float MIN_SCALE = 0.75f;
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0f);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1f);
view.setTranslationX(0f);
view.setScaleX(1f);
view.setScaleY(1f);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0f);
}
}
}
效果图(录制来自谷歌官网)
关注我的公众号(不是技术号),让你的职业发展除技术外,多一种可能