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>
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM