公司的项目想要一个这样效果的ViewPager展示
1、第一页和最后一页带有弹性效果
2、ViewPager底部图片随着页面滑动切换
3、ViewPager页面上的2个图片一个水平切换一个45角切换
这个效果如果简单的用原生的ViewPager实现肯定是解决不了的。
如果是原生的ViewPager,实现效果如下:
很明显这不是我需要的效果。
第一页和最后一页带有弹性效果
这个效果如何实现呢?我在网上找到了答案:https://stackoverflow.com/questions/13759862/android-viewpager-how-to-achieve-the-bound-effect
注意我在使用这个BounceBackViewPager时setPageMargin();会导致最后一页的弹性效果丢失。
ViewPager底部图片随着页面滑动切换
这个效果如何实现呢?我在网上找到了答案:https://www.jianshu.com/p/0e6b1d785e4f
具体实现是:
private Bitmap bg;
private Paint b = new Paint(Paint.ANTI_ALIAS_FLAG );
@Override
protected void dispatchDraw(Canvas canvas) {
if (this.bg != null) {
int width = this.bg.getWidth();
int height = this.bg.getHeight();
int count = getAdapter().getCount();
int x = getScrollX();
// 子View中背景图片需要显示的宽度,放大背景图或缩小背景图。
int n = height * getWidth() / getHeight();
/**
* (width - n) / (count - 1)表示除去显示第一个ViewPager页面用去的背景宽度,剩余的ViewPager需要显示的背景图片的宽度。
* getWidth()等于ViewPager一个页面的宽度,即手机屏幕宽度。在该计算中可以理解为滑动一个ViewPager页面需要滑动的像素值。
* ((width - n) / (count - 1)) /getWidth()也就表示ViewPager滑动一个像素时,背景图片滑动的宽度。
* x * ((width - n) / (count - 1)) / getWidth()也就表示ViewPager滑动x个像素时,背景图片滑动的宽度。
* 背景图片滑动的宽度的宽度可以理解为背景图片滑动到达的位置。
*/
int w = x * ((width - n) / (count - 1)) / getWidth();
canvas.drawBitmap(this.bg, new Rect(w, 0, n + w, height), new Rect(x, 0, x + getWidth(), getHeight()), this.b);
}
super.dispatchDraw(canvas);
}
public void setBackGroud(Bitmap paramBitmap) {
this.bg = paramBitmap;
this.b.setFilterBitmap(true);
}
ViewPager页面上的2个图片一个水平切换一个45角切换
这个效果的实现需要用ViewPager.PageTransformer,它可以用来切换ViewPager的页面的切换效果。
实现方式也很简单:
public class TranslationPageTransformer implements ViewPager.PageTransformer {
@Override
public void transformPage(@NonNull View itemView, float position) {
//这里考虑>=-1和<=1的情况
if (position >= -1 && position <= 1) {
View view = itemView.findViewById(R.id.iv1);
if (position < 0) {
//左进左出的情况
float offsetY = view.getTop() * Math.abs(position);
float offsetX = itemView.getWidth() * Math.abs(position);
view.setTranslationY(-offsetY);
view.setTranslationX(-offsetX);
} else {
//右进右出的情况
float offsetY = view.getTop() * Math.abs(position);
float offsetX = itemView.getWidth() * Math.abs(position);
view.setTranslationY(-offsetY);
view.setTranslationX(offsetX);
}
}
}
}
这样已经可以基本实现页面的45度角切换,但是第一个和最后一个弹性滑动的时候没有45度角滑动的效果,因为弹性滑动并不是原生ViewPager带有的,所以我给BounceViewPager增加了一个弹性滑动的回调监听。
/**
* 弹性滑动的监听
*/
public interface BounceListener {
/**
* @param view
* @param translaeX
*/
void onBounce(View view, float translaeX);
}
然后在他的弹性回调监听中增加45度角滑动效果。
mViewPager.setBounceListener(new BounceViewPager.BounceListener() {
@Override
public void onBounce(View child, float translaeX) {
final int position = child.getLeft() / child.getWidth();
//通过translateX给iv1一个Y轴上的位移
View view = child.findViewById(R.id.iv1);
if (view != null) {
if (position == mViewPager.getAdapter().getCount() - 1) {
//最后一个page
view.setTranslationY(-translaeX);
} else if (position == 0) {
//第一个page
view.setTranslationY(translaeX);
}
}
}
});
好了,上面的三个问题解决了,效果也就出来了。