ViewPager 3D轮播效果

一页显示三个,当中的呈放大状态,另外两页显示一部分并有灰色蒙层.效果如下:
3Dviewpager效果
这个实现起来还是比较容易的,不需要用到第三方的,使用viewpager完全可以实现.
布局文件如下,其中宽高可以自己定义:

                <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="287dp"
                android:layout_marginTop="12dp"
                android:clipChildren="false"
                android:gravity="center"
                android:orientation="vertical">

                <android.support.v4.view.ViewPager
                    android:id="@+id/view_pager"
                    android:layout_width="165dp"
                    android:layout_height="match_parent"/>
            </LinearLayout>

Activity代码如下,ZoomOutPageTransformer.java就是控制viewpager展示大小的蒙层,搜一下网上很多,等会我会把代码贴在下方:

viewPager.setOffscreenPageLimit(5);
viewPager.setPageTransformer(true, new ZoomOutPageTransformer());
adapter = new PageAdapter(this, jsonElements);
viewPager.setAdapter(adapter);

PageAdapter.java文件如下,数据源自己解决,这里图片加载使用的是glide.

public class PageAdapter extends PagerAdapter {
    private JsonArray jsonArray;
    private Context context;

public PageAdapter(Context context, JsonArray jsonArray) {
    this.context = context;
    this.jsonArray = jsonArray;
}

@Override
public int getCount() {
    return Integer.MAX_VALUE;
}


@Override
public Object instantiateItem(ViewGroup container, int position) {
    View view = LayoutInflater.from(context).inflate(R.layout.item_view, null);
    ImageView imageView = (ImageView) view.findViewById(R.id.iv_movie);
    position %= jsonArray.size();
    String img_url = jsonArray.get(position).getAsString();
    ImageLoadUtil.loadImage(container.getContext(), img_url, R.mipmap.icon_wx, imageView);
    container.addView(view);
    return view;
}


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

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    View view = (View) object;
    container.removeView(view);
}

}

现在这个轮播空间就写出来了,但是却不能自动轮播,需要用手滑动,那么我们就自己写一个handler来实现图片的自动轮播,代码中注释写的很清楚,不用一一讲解.
private static class ImageHandler extends Handler {

    /**
     * 请求更新显示的View。
     */
    protected static final int MSG_UPDATE_IMAGE = 1;
    /**
     * 请求暂停轮播。
     */
    protected static final int MSG_KEEP_SILENT = 2;
    /**
     * 请求恢复轮播。
     */
    protected static final int MSG_BREAK_SILENT = 3;
    /**
     * 记录最新的页号,当用户手动滑动时需要记录新页号,否则会使轮播的页面出错。
     * 例如当前如果在第一页,本来准备播放的是第二页,而这时候用户滑动到了末页,
     * 则应该播放的是第一页,如果继续按照原来的第二页播放,则逻辑上有问题。
     */
    protected static final int MSG_PAGE_CHANGED = 4;

    //轮播间隔时间
    protected static final long MSG_DELAY = 3000;

    //使用弱引用避免Handler泄露.这里的泛型参数可以不是Activity,也可以是Fragment等
    private WeakReference<MACDPushActivity> weakReference;
    private int currentItem = 0;

    protected ImageHandler(WeakReference<MACDPushActivity> wk) {
        weakReference = wk;
    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        MACDPushActivity activity = weakReference.get();
        if (activity == null) {
            //Activity已经回收,无需再处理UI了
            return;
        }
        //检查消息队列并移除未发送的消息,这主要是避免在复杂环境下消息出现重复等问题。
        if (activity.handler.hasMessages(MSG_UPDATE_IMAGE)) {
            activity.handler.removeMessages(MSG_UPDATE_IMAGE);
        }
        switch (msg.what) {
            case MSG_UPDATE_IMAGE:
                currentItem++;
                activity.viewPager.setCurrentItem(currentItem);
                //准备下次播放
                activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                break;
            case MSG_KEEP_SILENT:
                //只要不发送消息就暂停了
                break;
            case MSG_BREAK_SILENT:
                activity.handler.sendEmptyMessageDelayed(MSG_UPDATE_IMAGE, MSG_DELAY);
                break;
            case MSG_PAGE_CHANGED:
                //记录当前的页号,避免播放的时候页面显示不正确。
                currentItem = msg.arg1;
                break;
            default:
                break;
        }
    }
}

然后看一下,在activity中的调用,这里使用弱引用方式,防止内存溢出.

ImageHandler handler = new ImageHandler(new WeakReference<MACDPushActivity>(this));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            //配合Adapter的currentItem字段进行设置。
            @Override
            public void onPageSelected(int arg0) {
                handler.sendMessage(Message.obtain(handler, ImageHandler.MSG_PAGE_CHANGED, arg0, 0));
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
            }

        //覆写该方法实现轮播效果的暂停和恢复
        @Override
        public void onPageScrollStateChanged(int arg0) {
            switch (arg0) {
                case ViewPager.SCROLL_STATE_DRAGGING:
                    handler.sendEmptyMessage(ImageHandler.MSG_KEEP_SILENT);
                    break;
                case ViewPager.SCROLL_STATE_IDLE:
                    handler.sendEmptyMessageDelayed(ImageHandler.MSG_UPDATE_IMAGE, ImageHandler.MSG_DELAY);
                    break;
                default:
                    break;
            }
        }
    });

这样一个可以自动3D轮播就写好了.
附:ZoomOutPageTransformer.java

public class ZoomOutPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.9f;
private static final float MIN_ALPHA = 0.5f;
private static float defaultScale = 0.9f;
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(0);
        view.setScaleX(defaultScale);
        view.setScaleY(defaultScale);
    } 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(0);
        view.setScaleX(defaultScale);
        view.setScaleY(defaultScale);
    }
}}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值