美文网首页
ViewPager实现卡片式效果

ViewPager实现卡片式效果

作者: taoqx | 来源:发表于2020-03-10 16:22 被阅读0次

    参考:https://github.com/rubensousa/ViewPagerCards
    原理:

    1. 实现ViewPager.PageTransformer,接管ViewPager的页面转换操作。接口唯一方法transformPage空实现。

    2. ViewPager#setPageTransformer()设置自定义的实现类,ViewPager#addOnPageChangeListener,重写onPageScrolled方法。

    3. 卡片效果CardView#setMaxCardElevation(),且xml中app:cardUseCompatPadding="true"则会把elevation的值为padding间隔。

    package com.github.rubensousa.viewpagercards;
    
    import android.support.v4.view.ViewPager;
    import android.support.v7.widget.CardView;
    import android.util.Log;
    import android.view.View;
    
    
    public class ShadowTransformer implements ViewPager.OnPageChangeListener, ViewPager.PageTransformer {
    
        private ViewPager mViewPager;
        private CardAdapter mAdapter;
        private float mLastOffset;
        private boolean mScalingEnabled;
    
        public ShadowTransformer(ViewPager viewPager, CardAdapter adapter) {
            mViewPager = viewPager;
            viewPager.addOnPageChangeListener(this);
            mAdapter = adapter;
        }
    
        public void enableScaling(boolean enable) {
            if (mScalingEnabled && !enable) {
                // shrink main card
                CardView currentCard = mAdapter.getCardViewAt(mViewPager.getCurrentItem());
                if (currentCard != null) {
                    currentCard.animate().scaleY(1);
                    currentCard.animate().scaleX(1);
                }
            }else if(!mScalingEnabled && enable){
                // grow main card
                CardView currentCard = mAdapter.getCardViewAt(mViewPager.getCurrentItem());
                if (currentCard != null) {
                    currentCard.animate().scaleY(1.1f);
                    currentCard.animate().scaleX(1.1f);
                }
            }
    
            mScalingEnabled = enable;
        }
    
        @Override
        public void transformPage(View page, float position) {
    
        }
    
        /**
         * 原currentItem缩小比例、新currentItem放大比例
         * 1、positionOffset控制CardView的animate
         *      positionOffset范围:[0,1)
         *      右滑时positionOffset从0到1逐渐增大,到达下一个item时,position加1,positionOffset归0
         *      左滑时positionOffset从1到0逐渐减小,刚开始滑动时position就减1,positionOffset减小到0
         * 2、positionOffset与上一次比较判断左滑右滑
         * 3、效果上来看,只有当前item和下一个要展示的item需要动画效果;如右滑时,当前item左侧的item无需动画效果
         * @param position
         * @param positionOffset
         * @param positionOffsetPixels
         */
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            Log.d("Trans","position = " + position + " ,positionOffset = "  + positionOffset);
            int realCurrentPosition;
            int nextPosition;
            float baseElevation = mAdapter.getBaseElevation();
            float realOffset;
            boolean goingLeft = mLastOffset > positionOffset;
    
            // If we're going backwards, onPageScrolled receives the last position
            // instead of the current one
            if (goingLeft) {
                realCurrentPosition = position + 1; //左滑时,position其实是左侧item位置
                nextPosition = position;
                realOffset = 1 - positionOffset;    //左滑时,positionOffset 1 -> 0
            } else {
                nextPosition = position + 1;
                realCurrentPosition = position;
                realOffset = positionOffset;
            }
    
            // Avoid crash on overscroll
            if (nextPosition > mAdapter.getCount() - 1
                    || realCurrentPosition > mAdapter.getCount() - 1) {
                return;
            }
    
            CardView currentCard = mAdapter.getCardViewAt(realCurrentPosition);
    
            // This might be null if a fragment is being used
            // and the views weren't created yet
            if (currentCard != null) {
                if (mScalingEnabled) {
                    currentCard.setScaleX((float) (1 + 0.1 * (1 - realOffset)));
                    currentCard.setScaleY((float) (1 + 0.1 * (1 - realOffset)));
                }
            }
    
            CardView nextCard = mAdapter.getCardViewAt(nextPosition);
    
            // We might be scrolling fast enough so that the next (or previous) card
            // was already destroyed or a fragment might not have been created yet
            if (nextCard != null) {
                if (mScalingEnabled) {
                    nextCard.setScaleX((float) (1 + 0.1 * (realOffset)));
                    nextCard.setScaleY((float) (1 + 0.1 * (realOffset)));
                }
            }
    
            mLastOffset = positionOffset;
        }
    
        @Override
        public void onPageSelected(int position) {
    
        }
    
        @Override
        public void onPageScrollStateChanged(int state) {
    
        }
    }
    
    

    相关文章

      网友评论

          本文标题:ViewPager实现卡片式效果

          本文链接:https://www.haomeiwen.com/subject/fptgdhtx.html