Android----各种效果的3DViewPager效果(一)

公司项目中有要求类似于画廊效果,网上找了好多的文章,写的都比较复杂,代码篇幅都比较长,实在是看不下去,实现的效果和预想的也不太一样,之后看见了Alex_MaHao的博客http://blog.csdn.net/lisdye2/article/details/52315008,实现的效果和我想要的差不多,而且代码比较简单容易理解,核心的代码也是在10行左右,而且也可以根据需求来更改核心代码,实现各种各样的3DViewPager的效果,建议大家先看一下这篇文章

这篇文章所介绍的效果和我需要的的确一样,但是真正用到项目中的时候发现的存在的问题.因为上述文章每一个Pager所承接的是一个View,也就是图片,然后根据每一页的滑动的偏移量来添加Padding,实现了缩放的效果,而我需要的Pager所承接的ViewGroup,也就是说Pager里有多个View,仅仅是添加Padding,外层的View有缩放的效果,但是子View却没有.效果如下

你会发现,最外层的布局虽然有缩放效果,但是里面的字体没有.所以我直接用缩放动画来代替Padding,也就是根据每一页的滑动的偏移量来进行缩放的设置.效果如下

我加了透明和缩放的动画(缩放的倍数有点小,不太明显).代码如下

 

CoverFlowAdapter.java

 

 

public class CoverFlowAdapter extends PagerAdapter implements ViewPager.OnPageChangeListener {

    /**
     * 子元素的集合
     */
    private List<View> mViewList;

    /**
     * 滑动监听的回调接口
     */
    private OnPageSelectListener listener;

    private Context mContext;

    private float mPositionOffset=0;

    public CoverFlowAdapter(List<View> mImageViewList, Context context) {
        this.mViewList = mImageViewList;
        mContext = context;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView(mViewList.get(position));
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        View view = mViewList.get(position);
        container.addView(view);

        return view;
    }

    @Override
    public int getCount() {
        return mViewList == null ? 0 : mViewList.size();
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == object;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        // 该方法回调ViewPager 的滑动偏移量
        if (mViewList.size() > 0 && position < mViewList.size()) {
            //当前手指触摸滑动的页面,从0页滑动到1页 offset越来越大,padding越来越大
            mViewList.get(position).setScaleX(1 - positionOffset * 0.17f);
            mViewList.get(position).setScaleY(1 - positionOffset * 0.17f);
            mViewList.get(position).setAlpha(1 - positionOffset * 0.5f);
//            mViewList.get(position).setTranslationX(dp2px(60) * positionOffset);

            // position+1 为即将显示的页面,越来越大
            if (position < mViewList.size() - 1) {
                mViewList.get(position + 1).setScaleX(0.83f + positionOffset * 0.17f);
                mViewList.get(position + 1).setScaleY(0.83f + positionOffset * 0.17f);
                mViewList.get(position + 1).setAlpha(0.5f + positionOffset * 0.5f);
            }
        }
        mPositionOffset=positionOffset;
    }

    @Override
    public void onPageSelected(int position) {
        // 回调选择的接口
        if (listener != null) {
            listener.select(position);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    /**
     * 当将某一个作为最中央时的回调
     *
     * @param listener
     */
    public void setOnPageSelectListener(OnPageSelectListener listener) {
        this.listener = listener;
    }

}// 该方法回调ViewPager 的滑动偏移量
        if (mViewList.size() > 0 && position < mViewList.size()) {
            //当前手指触摸滑动的页面,从0页滑动到1页 offset越来越大,padding越来越大
            mViewList.get(position).setScaleX(1 - positionOffset * 0.17f);
            mViewList.get(position).setScaleY(1 - positionOffset * 0.17f);
            mViewList.get(position).setAlpha(1 - positionOffset * 0.5f);
//            mViewList.get(position).setTranslationX(dp2px(60) * positionOffset);

            // position+1 为即将显示的页面,越来越大
            if (position < mViewList.size() - 1) {
                mViewList.get(position + 1).setScaleX(0.83f + positionOffset * 0.17f);
                mViewList.get(position + 1).setScaleY(0.83f + positionOffset * 0.17f);
                mViewList.get(position + 1).setAlpha(0.5f + positionOffset * 0.5f);
            }
        }
        mPositionOffset=positionOffset;
    }

    @Override
    public void onPageSelected(int position) {
        // 回调选择的接口
        if (listener != null) {
            listener.select(position);
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    /**
     * 当将某一个作为最中央时的回调
     *
     * @param listener
     */
    public void setOnPageSelectListener(OnPageSelectListener listener) {
        this.listener = listener;
    }

}

 

 

CoverFlowViewPager.java
public class CoverFlowViewPager extends RelativeLayout implements OnPageSelectListener {

    private CoverFlowAdapter mAdapter;

    private ViewPager mViewPager;

    //需要显示的视图集合,也就是每个Pager所要展示的View
    private List<View> mViewList = new ArrayList<>();

    private OnPageSelectListener listener;

    public CoverFlowViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
        inflate(context, R.layout.widget_cover_flow,this);
        mViewPager = (ViewPager) findViewById(R.id.vp_conver_flow);
        init();
    }

    //初始化方法
    private void init() {
        // 构造适配器,传入数据源
        mAdapter = new CoverFlowAdapter(mViewList,getContext());
        // 设置选中的回调
        mAdapter.setOnPageSelectListener(this);
        // 设置适配器
        mViewPager.setAdapter(mAdapter);
        // 设置滑动的监听,因为adpter实现了滑动回调的接口,所以这里直接设置adpter
        mViewPager.addOnPageChangeListener(mAdapter);
        // 自己百度
        mViewPager.setOffscreenPageLimit(5);

        // 设置触摸事件的分发
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // 传递给ViewPager 进行滑动处理
                return mViewPager.dispatchTouchEvent(event);
            }
        });

    }

    /**
     * 设置显示的数据,进行一层封装
     * @param lists
     */
    public void setViewList(List<View> lists){
        if(lists==null){
            return;
        }
        mViewList.clear();
        for(View view:lists){

            FrameLayout layout = new FrameLayout(getContext());
            // 设置padding 值,默认缩小
            layout.setScaleX(0.83f);
            layout.setScaleY(0.83f);
            layout.setAlpha(0.5f);
//            layout.setTranslationX(mAdapter.dp2px(-60));
            layout.addView(view);
            mViewList.add(layout);
        }
        // 刷新数据
        mAdapter.notifyDataSetChanged();
        mViewList.get(0).bringToFront();

    }


    /**
     * 当将某一个作为最中央时的回调
     * @param listener
     */
    public void setOnPageSelectListener(OnPageSelectListener listener) {
        this.listener = listener;
    }


    // 显示的回调
    @Override
    public void select(int position) {
        if(listener!=null){
            listener.select(position);
        }
    }
} layout.setScaleX(0.83f);
            layout.setScaleY(0.83f);
            layout.setAlpha(0.5f);
//            layout.setTranslationX(mAdapter.dp2px(-60));
            layout.addView(view);
            mViewList.add(layout);
        }
        // 刷新数据
        mAdapter.notifyDataSetChanged();
        mViewList.get(0).bringToFront();

    }


    /**
     * 当将某一个作为最中央时的回调
     * @param listener
     */
    public void setOnPageSelectListener(OnPageSelectListener listener) {
        this.listener = listener;
    }


    // 显示的回调
    @Override
    public void select(int position) {
        if(listener!=null){
            listener.select(position);
        }
    }
}

 

 

OnPageSelectListener.java
public interface OnPageSelectListener {

    void select(int position);
}

 

 

R.layout.widget_cover_flow

 

 

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:clipChildren="false">

    <android.support.v4.view.ViewPager
        android:id="@+id/vp_conver_flow"
        android:layout_width="120dp"
        android:layout_height="260dp"
        android:layout_centerHorizontal="true"
        android:clipChildren="false" />

</RelativeLayout>

 

 

下一篇我会介绍一个稍微复杂一点的3DViewPager的效果
源码下载点击这里,本来想设置为免费,但是不太清楚怎么设置,只能设置为1了,如果积分不够,加我QQ:954831816
 

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值