Android 轮播

import android.app.Activity;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class Carousel extends RelativeLayout {

    private CarouselPager mPager;
    private Context mContext;
    private int mResourceId = -1;
    private Carousel self;
    private CarouselDelegate mDelegate;
    private CarouselAdapter mAdapter;
    private int mCurrentItem = 1;
    private int mItemCount;

    public Carousel(Context context) {
        super(context);
        init(context);
    }

    public Carousel(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public Carousel(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        self = this;

        mAdapter = new CarouselAdapter();

        mPager = new CarouselPager(mContext);
        RelativeLayout.LayoutParams layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
        addView(mPager,layoutParams);

        mPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {

//                Log.d("Selected", "onPageSelected: " + position);
                mCurrentItem = position;
                int display_index = mCurrentItem;
                if (position == 0) {
                    display_index = mItemCount;
                } else if (position == mItemCount + 1) {
                    display_index = 1;
                } else {
                    display_index = position;

                    // 代理方法在此调用避免两端点的索引重复出现
                    if (mDelegate != null) {
                        mDelegate.carouselDidShowItem(self,display_index - 1);
                    }
                }


            }

            @Override
            public void onPageScrollStateChanged(int state) {

                // 解决两端切换时闪屏
                if (state == ViewPager.SCROLL_STATE_IDLE) {
                    if (mCurrentItem == mPager.getAdapter().getCount() - 1) {
                        mPager.setCurrentItem(1, false);
                    }
                    else if (mCurrentItem == 0) {
                        mPager.setCurrentItem(mPager.getAdapter().getCount() - 2, false);
                    }
                }
            }
        });
        mPager.setAdapter(mAdapter);
        reloadData();
    }

    public void registResourceId(int resourceId) {
        mResourceId = resourceId;
    }

    public void setDelegate(CarouselDelegate delegate) {
        mDelegate = delegate;
    }

    public void reloadData() {
        mAdapter.notifyDataSetChanged();
        mCurrentItem = 1;
        mPager.setCurrentItem(mCurrentItem,false);
        if (mAutoScroll) {

            startAutoScroll();
        }
    }



    public interface CarouselDelegate {

        void carouselWillShowItem(Carousel carousel,View cell,int index);
        void carouselDidShowItem(Carousel carousel,int index);
        int  carouselNumberOfItems(Carousel carousel);

    }

    public class CarouselAdapter extends PagerAdapter {

        ArrayList<View> mReusePool = new ArrayList<>();

        @Override
        public int getCount() {
            if (mDelegate == null || mResourceId == -1) {

                return mItemCount = 0;
            } else {
                int number = mDelegate.carouselNumberOfItems(self);
                if (number == 0) {
                    return mItemCount = 0;
                } else {
                    mItemCount = number;
                    return number + 2;
                }
            }

        }

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

        @Override
        public int getItemPosition(Object object) {
//            return super.getItemPosition(object);
            return POSITION_NONE; // 解决notifyDataChange后界面没更新
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {

            View cell = (View) object;
            container.removeView(cell);
            mReusePool.add(cell);
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            View cell = null;
            if (mReusePool.isEmpty()) {

                cell = (View) LayoutInflater.from(mContext).inflate(mResourceId,null);

            } else {
                cell = mReusePool.get(0);
                mReusePool.remove(cell);
            }


            int index = position;
            if (position == 0) {
                index = mItemCount - 1;
            } else if (position == mItemCount + 1) {
                index = 0;
            } else {
                index = position - 1;
            }


            if (mDelegate!= null) {
                mDelegate.carouselWillShowItem(self,cell,index);
            }

            container.addView(cell);

            return cell;
        }
    }

    private Timer mTimer;
    private TimerTask mTimerTask;
    private boolean mAutoScroll = false;
    private int mAutoScrollFlag = 0; // Timer开始第一次执行无效
    private int mScrollTimeInterval = 10; // 单位秒

    public void setAutoScroll(boolean autoScroll) {
        mAutoScroll = autoScroll;
        if (mAutoScroll) {
            startAutoScroll();
        } else {
            stopAutoScroll();
        }
    }

    public boolean getAutoScroll() {
        return mAutoScroll;
    }

    public void setScrollTimeInterval(int scrollTimeInterval) {
        this.mScrollTimeInterval = scrollTimeInterval;
    }

    public int getScrollTimeInterval() {
        return this.mScrollTimeInterval;
    }

    private void startAutoScroll() {
        if (mItemCount == 0) {
            return;
        }

        stopAutoScroll();

        mTimer = new Timer();
        mTimerTask = new TimerTask() {
            @Override
            public void run() {
                ((Activity)mContext).runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (mAutoScrollFlag == 0) {
                            mAutoScrollFlag = 1;
                        } else {
                            mPager.setCurrentItem(mCurrentItem + 1,true);
                        }
                    }
                });
            }
        };
        mTimer.schedule(mTimerTask,new Date(),1000 * mScrollTimeInterval);
    }

    private void stopAutoScroll() {
        if (mTimer != null) {
            mTimer.cancel();
            mTimer = null;
            mTimerTask = null;
            mAutoScrollFlag = 0;
        }
    }

    private class CarouselPager extends ViewPager {

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

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

        @Override
        public boolean onTouchEvent(MotionEvent event) {

            if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
                stopAutoScroll();
            }

            if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) {
                if (mAutoScroll) {
                    startAutoScroll();
                }
            }

            return super.onTouchEvent(event);
        }
    }
}

 

posted @ 2018-04-28 15:21  Emerys  阅读(179)  评论(0编辑  收藏  举报