android实现3D Gallery 轮播效果,触摸时停止轮播

1、轮播控件涉及到的两个类

CarouselViewPager.java
public class CarouselViewPager extends ViewPager {
    @IntDef({RESUME, PAUSE, DESTROY})
    @Retention(RetentionPolicy.SOURCE)
    public @interface LifeCycle {
    }

    public static final int RESUME = 0;
    public static final int PAUSE = 1;
    public static final int DESTROY = 2;
    /**
     * 生命周期状态,保证{@link #mCarouselTimer}在各生命周期选择执行策略
     */
    private int mLifeCycle = RESUME;
    /**
     * 是否正在触摸状态,用以防止触摸滑动和自动轮播冲突
     */
    private boolean mIsTouching = false;

    /**
     * 超时时间
     */
    private int timeOut = 2;

    /**
     * 轮播定时器
     */
    private ScheduledExecutorService mCarouselTimer;

    /**
     * 有数据时,才开始进行轮播
     */
    private boolean hasData;

    public CarouselViewPager(Context context) {
        super(context);
    }

    public CarouselViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setLifeCycle(@LifeCycle int lifeCycle) {
        this.mLifeCycle = lifeCycle;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mIsTouching = true;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mIsTouching = false;
                break;
        }
        return super.onTouchEvent(ev);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        startTimer();
    }

    public void startTimer() {
        if (!hasData) {
            return;
        }
        shutdownTimer();
        mCarouselTimer = Executors.newSingleThreadScheduledExecutor();
        mCarouselTimer.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                switch (mLifeCycle) {
                    case RESUME:
                        if (!mIsTouching
                                && getAdapter() != null
                                && getAdapter().getCount() > 1) {
                            post(new Runnable() {
                                @Override
                                public void run() {
                                    setCurrentItem(getCurrentItem() + 1);
                                }
                            });
                        }
                        break;
                    case PAUSE:
                        break;
                    case DESTROY:
                        shutdownTimer();
                        break;
                }
            }
        }, 0, 1000 * timeOut, TimeUnit.MILLISECONDS);
    }

    public void setHasData(boolean hasData) {
        this.hasData = hasData;
    }

    public void setTimeOut(int timeOut) {
        this.timeOut = timeOut;
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        shutdownTimer();
    }

    private void shutdownTimer() {
        if (mCarouselTimer != null && mCarouselTimer.isShutdown() == false) {
            mCarouselTimer.shutdown();
        }
        mCarouselTimer = null;
    }
}
CarouselPagerAdapter.java
/**
 * @描述 @link CarouselViewPager 轮播控件}所需的adapter
 */

public abstract class CarouselPagerAdapter<V extends CarouselViewPager> extends PagerAdapter {
    /**
     * 系数,可以自行设置,但又以下原则需要遵循:
     * <ul>
     * <li>必须大于1</li>
     * <li>尽量小</li>
     * </ul>
     */
    private static final int COEFFICIENT = 10;
    private V mViewPager;

    public CarouselPagerAdapter(V viewPager) {
        this.mViewPager = viewPager;
    }

    /**
     * @return 实际数据数量
     */
    @IntRange(from = 0)
    public abstract int getRealDataCount();

    @Override
    public final int getCount() {
        long realDataCount = getRealDataCount();
        if (realDataCount > 1) {
            realDataCount = getRealDataCount() * COEFFICIENT;
            realDataCount = realDataCount > Integer.MAX_VALUE ? Integer.MAX_VALUE : realDataCount;
        }
        return (int) realDataCount;
    }

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

    @Override
    public final Object instantiateItem(ViewGroup container, int position) {
        position = position % getRealDataCount();
        return this.instantiateRealItem(container, position);
    }

    public abstract Object instantiateRealItem(ViewGroup container, int position);

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

    @Override
    public final void finishUpdate(ViewGroup container) {
        // 数量为1,不做position替换
        if (getCount() <= 1) {
            return;
        }

        int position = mViewPager.getCurrentItem();
        // ViewPager的更新即将完成,替换position,以达到无限循环的效果
        if (position == 0) {
            position = getRealDataCount();
            mViewPager.setCurrentItem(position, false);
        } else if (position == getCount() - 1) {
            position = getRealDataCount() - 1;
            mViewPager.setCurrentItem(position, false);
        }
    }
}

2、实现3D效果需要用到的类

public class GalleryTransformer implements ViewPager.PageTransformer {
    @Override
    public void transformPage(View view, float position) {
        float scale = 0.5f;
        float scaleValue = 1 - Math.abs(position) * scale;
        view.setScaleX(scaleValue);
        view.setScaleY(scaleValue);
        view.setAlpha(scaleValue);
        view.setPivotX(view.getWidth() * (1 - position - (position > 0 ? 1 : -1) * 0.75f) * scale);
        view.setElevation(position > -0.25 && position < 0.25 ? 1 : 0);
    }
}

3、使用方法

public class MainActivity extends AppCompatActivity {
    private CarouselViewPager viewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager = (CarouselViewPager) findViewById(R.id.id_viewpager);

        ImagePagerAdapter adapter = new ImagePagerAdapter(this, viewPager);
        viewPager.setOffscreenPageLimit(3);
        viewPager.setAdapter(adapter);
        // 设置轮播时间
        viewPager.setTimeOut(5);
        // 设置3d效果
        viewPager.setPageTransformer(true, new GalleryTransformer());
        // 设置已经有数据了,可以进行轮播,一般轮播的图片等数据是来源于网络,网络数据来了后才设置此值,此处因为是demo,所以直接赋值了
        viewPager.setHasData(true);
        // 开启轮播
        viewPager.startTimer();
    }
}
public class ImagePagerAdapter extends CarouselPagerAdapter<CarouselViewPager> {

    public ImagePagerAdapter(Context context, CarouselViewPager viewPager) {
        super(viewPager);
    }

    int[] imgRes = {
            R.drawable.img_wallhaven_426244,
            R.drawable.img_wallhaven_431231,
            R.drawable.img_wallhaven_432740,
   /*         R.drawable.img_wallhaven_426244,
            R.drawable.img_wallhaven_431231,
            R.drawable.img_wallhaven_432740,
            R.drawable.img_wallhaven_426244,
            R.drawable.img_wallhaven_431231,
            R.drawable.img_wallhaven_432740,*/
    };

    @Override
    public Object instantiateRealItem(ViewGroup container, int position) {
        ImageView view = new ImageView(container.getContext());
        view.setScaleType(ImageView.ScaleType.FIT_XY);
        view.setAdjustViewBounds(true);
        view.setImageResource(imgRes[position]);
        view.setLayoutParams(new LinearLayout.LayoutParams(900, 400));
        container.addView(view);
        return view;
    }

    @Override
    public int getRealDataCount() {
        return imgRes != null ? imgRes.length : 0;
    }
}

ps:

ImagePagerAdapter.java是一个普通的PagerAdapter类,用户自定义,需要继承CarouselPagerAdapter<CarouselViewPager>并重写CarouselPagerAdapter的构造方法,在
public Object instantiateRealItem(ViewGroup container, int position) 方法中定义界面的具体显示
 public int getRealDataCount() {
        return imgRes != null ? imgRes.length : 0;
    }方法中返回具体的页面总数


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

    <com.twiceyuan.galleryviewpager.CarouselViewPager
        android:id="@+id/id_viewpager"
        android:layout_width="240dp"
        android:layout_height="120dp"
        android:clipChildren="false"/>

</RelativeLayout>
 
 
时间: 2024-11-06 03:29:13

android实现3D Gallery 轮播效果,触摸时停止轮播的相关文章

Android实现图片轮显效果——自定义ViewPager控件

一.问题概述 使用ViewPager控件实现可横向翻页.水平切换图片等效果,但ViewPager需要手动滑动才能切换页面,图片轮显效果的效果本质上就是在ViewPager控件的基础上让它能自动的进行切换,所以实现图片轮显步骤如下: 1.  扩展ViewPager自定义一个MyScrollImageView类 2.  为MyScrollImageView定义适配器,装载图片信息 3.  定义图片滑动动画时间控制类 接下来我们就一步步实现下图案例: 二.实现套路 1.为自定义ViewPager控件编

用JQ去实现一个轮播效果

前提:对于这几天学到的用JQ去实现轮播效果一步步的做一个梳理. 首先肯定是轮播的HTML和CSS样式了: <body> <div class="pic"> <div class="inner"> <img src="img/1.jpg" alt=""> <img src="img/2.jpg" alt=""> <img s

jquery特效(4)—轮播图②(定时自动轮播)

今天逛了一天街,把田子坊.人民广场.静安寺公园遛了一遍,吃了很多好吃的东西~~~然后就回公司好好地研究代码了,也算是把定时自动轮播程序写出来了,特意说明一下,这次的轮播图是在昨天随笔中jquery特效(3)—轮播图①(手动点击轮播)的基础上写出来的,也就是本次随笔展示的是手动点击轮播效果以及定时自动轮播效果的程序,建议想连贯学习的小伙伴把我昨天写的笔记看完后再看这篇文章~~~~ 下面来看看我做的最终定时自动轮播效果以及手动点击轮播效果: 对于上面的展示动画速度比较快的原因是因为我的截图软件是绿色

Android中使用ViewPager实现屏幕页面切换和页面轮播效果

之前关于如何实现屏幕页面切换,写过一篇博文<Android中使用ViewFlipper实现屏幕切换>,相比ViewFlipper,ViewPager更适用复杂的视图切换,而且Viewpager有自己的adapter,这也让其适应复杂对象,实现数据的动态加载. ViewPager是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一,利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等. 下面我们就展示下Vie

Android使用ViewPager实现左右循环滑动及轮播效果

ViewPager是一个常用的android组件,不过通常我们使用ViewPager的时候不能实现左右无限循环滑动,在滑到边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其他页面的信息. 为此我查阅了网络上现有的一些关于实现这样效果的例子,但都不是很满意,经过反复实验,在这里总结并分享给大家,希望能有所帮助. 循环滑动效果的实现:PagerAdap

Android UI - 实现广告Banner轮播效果

Android UI - 实现广告Banner轮播效果 前言 本篇博客要分享的一个效果是实现广告Banner轮播效果,这个效果也比较常见,一些视频类应用就经常有,就拿360影视大全来举例吧: 用红框框住的那个效果就是小巫今天要分享的,先来思考一下会用到什么控件?有什么用户体验? 控件我们可能一下子就可以想到的自然是ViewPager,没错!用到的就是ViewPager,那么它会有什么用户体验呢,它可能有以下几个体验: 1. 间隔不停的切换图片,指示器也跟着变 2. 点击图片可以跳转到指定的页面

安卓首页图片轮播效果(淘宝、京东首页广告效果)

直奔主题: 1.主要原理就是利用定时任务器定时切换ViewPager的页面. 2.里面用了一个读取网络图片的插件.做client使用本地图片轮播的也非常少. 先上个效果图: 项目代码结构截图: 自己定义View 的布局文件layout_slideshow.xml: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.and

ViewPager手势切换页面+图片左右轮播效果(精简版本)

效果图是:手势可以左右滑动界面,并且自动从第一张开始轮播到最后一张图片,紧接着开始从最后一张图片开始向反方向第一张轮播 如果你需要轮播效果,(我这个是精简版本的)  如果你需要手势来回切换图片  如果你不需要ui提供定位圆点 那么这篇博客  值得你看看 源码地址就不传了,代码已经贴出,你可以随便放5张图片即可 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android

viewPager+Handler+Timer简单实现广告轮播效果

基本思想是在Avtivity中放一个ViewPager,然后通过监听去实现联动效果,代码理由详细的解释,我就不说了. MainActivity.java 1 package com.example.administrator.imageviewlunbodemo; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.Message