一个效果不错的ViewPager

公司的项目想要一个这样效果的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);
                    }
                }
            }
        });

好了,上面的三个问题解决了,效果也就出来了。

项目地址:https://github.com/Siy-Wu/BounceViewPage

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值