• 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>
     
     
  • 相关阅读:
    建造者模式
    js日期转化(计算一周的日期)
    vue实现全选效果
    less入门
    使用node初始化项目
    ES5新语法forEach和map及封装原理
    es6中的promise对象
    深入理解jsonp跨域请求原理
    markdown语法与使用
    Ajax商品分类三级联动实现
  • 原文地址:https://www.cnblogs.com/baiyi168/p/6650557.html
Copyright © 2020-2023  润新知