Android ViewPager实现循环轮播图

一、原理

ViewPager是Android中使用频率相对较高的view组件,同时对滑动过程中的事件进行了处理,因此非常适合轮播图。关于轮播图的实现,有很多方法,使用HorizontalView或者RecylerView也可以实现,但是需要处理fling操作,这里我们用ViewPager避免这些工作。 网上有很多关于ViewPager轮播的轮播实现,其原理大多数给PagerAdapter的getCount 放大N倍,N大于100,1000等。这里我们使用另一种思路,数据映射。

数据映射方案:假设原始数据有N张图片数据,我们将数据N+2,然后将原来的第一张图片放到新的 索引为N+1的位置,原来的最后一张图片放到第一张图片,这样构建了一个新的数据。当图片滑动到 position==0 时,我们使用viewPager.setCurrentItem(N,false) ,当position=N+1时,我们使用viewPager.setCurrentItem(1,false);便可实无限滑动。当然,以上方案可行,也很简单,但是却破坏了原始数据,我们可以通过算法实现原始数据不被破坏的实现方式,计算出真实的数据索引。

 private int getRealPosition(int position) {
            int realPosition = position;
            if(InnerWrapperPagerAdapter.this.getCount()>1){
                if(position==0){
                    realPosition = (getCount()-2)-1;
                }else if(position==getCount()-1){
                    realPosition = 0;
                }else{
                    realPosition = position-1;
                }
            }
            return realPosition;
        }

二、代码实现

public class AutoBannerView extends ViewPager implements Handler.Callback {

    private OnPagerChangeListener mOpageChangeListener;

    public static long TIME_WAIT = 3000;  //每3秒轮播一次
    private boolean isPlaying = false;

    private OnPagerSelectedListener mOnPagerSelectedListener;

    private boolean lastStateIsPlaying = false; //停止轮播之前的状态
    //private   static  AutoBannerRunnable autoRunnable = null;

    private final  Handler  mTaskHandler;
    private static final int ACTION_PLAY = 1024*1024;

    public AutoBannerView(Context context) {
        this(context,null);
    }

    public AutoBannerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setOverScrollMode(OVER_SCROLL_NEVER);
        setOffscreenPageLimit(5);
        if(mOpageChangeListener==null){
            mOpageChangeListener = new OnPagerChangeListener(this);
        }
        mTaskHandler = new Handler(Looper.getMainLooper(),this);

    }

    public void setOnPagerSelectedListener(OnPagerSelectedListener mOnPagerSelectedListener) {
        this.mOnPagerSelectedListener = mOnPagerSelectedListener;
    }

    @Override
    public boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params) {
        return super.addViewInLayout(child, index, params);
    }

    @Override
    protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params, boolean preventRequestLayout) {
        return super.addViewInLayout(child, index, params, preventRequestLayout);
    }

    @Override
    public void setAdapter(PagerAdapter adapter) {
        if (null != getAdapter()) {
            removeOnPageChangeListener(mOpageChangeListener);
        }
        if (null == adapter) {
            super.setAdapter(null);
        } else {
            super.setAdapter(new InnerWrapperPagerAdapter(adapter,this));
            addOnPageChangeListener(mOpageChangeListener);
            if(adapter.getCount()>1){
                setCurrentItem(1,false);  //getCount>1 ,初始化时默认显示原始数据的第0位,也就是新的PagerAdapter的第二位
                startPlay();
            }else if(adapter.getCount()>0){
                mOpageChangeListener.onPageSelected(0);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        finishResetPosition();

        final ViewParent parent = this.getParent();
        switch (ev.getActionMasked()){
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:

                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(true);
                    //解决ViewPager嵌套ViewPager导致无法滑动的问题
                }
                if(isPlaying){
                    stopPlay();
                }

                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (parent != null) {
                    parent.requestDisallowInterceptTouchEvent(false);
                    //解决ViewPager嵌套ViewPager导致无法滑动的问题
                }
                if(lastStateIsPlaying){
                    startPlay();
                }
                break;
        }
        return super.onTouchEvent(ev);
    }

    public PagerAdapter getRealAdapter() {
        final PagerAdapter adapter = getAdapter();
        if( adapter instanceof  InnerWrapperPagerAdapter){
            return ((InnerWrapperPagerAdapter) adapter).getTargetPagerAdapter();
        }
        return adapter;
    }

    public static class AdapterDataSetObserver extends  DataSetObserver{
        private InnerWrapperPagerAdapter  innerWrapperPagerAdapter;
        private AutoBannerView autoBannerView;

        public AdapterDataSetObserver(InnerWrapperPagerAdapter innerWrapperPagerAdapter,AutoBannerView autoBannerView) {
            this.innerWrapperPagerAdapter = innerWrapperPagerAdapter;
            this.autoBannerView  = autoBannerView;
        }
        @Override
        public void onChanged() {
            super.onChanged();
            innerWrapperPagerAdapter.notifyDataSetChanged();
            if(innerWrapperPagerAdapter.getCount()>1){
                final int currentItem = this.autoBannerView.getCurrentItem();
                if(currentItem==0){
                    this.autoBannerView.setCurrentItem(1,false);
                }

                if(this.autoBannerView.isPlaying || this.autoBannerView.lastStateIsPlaying){
                    this.autoBannerView.startPlay();
                }
            }
            if(innerWrapperPagerAdapter.getCount()>0 &&this.autoBannerView.mOpageChangeListener!=null) {
                this.autoBannerView.mOpageChangeListener.onPageSelected(this.autoBannerView.getCurrentItem());
            }
        }

    }

    /**
     * 包装PagerAdapter,实现数据映射
     */
    private static class  InnerWrapperPagerAdapter extends PagerAdapter{

        private final AdapterDataSetObserver adapterDataSetObserver;

        private PagerAdapter mPagerAdapter;

        public InnerWrapperPagerAdapter(PagerAdapter pagerAdapter,AutoBannerView autoBannerView) {
            this.mPagerAdapter = pagerAdapter;
            this.adapterDataSetObserver = new AdapterDataSetObserver(this,autoBannerView);
            if(this.mPagerAdapter!=null){
                this.mPagerAdapter.registerDataSetObserver(this.adapterDataSetObserver);
            }
        }

        public PagerAdapter getTargetPagerAdapter() {
            return mPagerAdapter;
        }

        @Override
        public int getCount() {
            if(mPagerAdapter!=null) {  //如果数据大于1,说明可以轮播
                return mPagerAdapter.getCount() > 1 ? mPagerAdapter.getCount() + 2 : mPagerAdapter.getCount();
            }
            return 0;
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            if(mPagerAdapter!=null) {
                return mPagerAdapter.isViewFromObject(view, object);
            }
            return false;
        }

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            if(mPagerAdapter!=null) {
                int realPosition = getRealPosition(position);
                return mPagerAdapter.instantiateItem(container, realPosition);
            }
            return super.instantiateItem(container,position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            if(mPagerAdapter!=null) {
                int realPosition = getRealPosition(position);
                mPagerAdapter.destroyItem(container, realPosition, object);
            }else{
                super.destroyItem(container,position,object);
            }
        }

        private int getRealPosition(int position) {
            int realPosition = position;
            if(InnerWrapperPagerAdapter.this.getCount()>1){
                if(position==0){
                    realPosition = (getCount()-2)-1;
                }else if(position==getCount()-1){
                    realPosition = 0;
                }else{
                    realPosition = position-1;
                }
            }
            return realPosition;
        }

        @Override
        public int getItemPosition(Object object) {
            if(mPagerAdapter!=null){
                return mPagerAdapter.getItemPosition(object);
            }
            return super.getItemPosition(object);
        }

        @Override
        public CharSequence getPageTitle(int position) {
            if(mPagerAdapter!=null) {
                int realPosition = getRealPosition(position);
                return mPagerAdapter.getPageTitle(realPosition);
            }else{
                return super.getPageTitle(position);
            }
        }

        @Override
        public float getPageWidth(int position) {
            if(mPagerAdapter!=null){
                int realPosition = getRealPosition(position);
                return mPagerAdapter.getPageWidth(realPosition);
            }
            return super.getPageWidth(position);
        }

        @Override
        public void startUpdate(ViewGroup container) {
            if(mPagerAdapter!=null) {
                mPagerAdapter.startUpdate(container);
            }else{
                super.startUpdate(container);
            }
        }

        @Override
        public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if(mPagerAdapter!=null) {
                int realPosition = getRealPosition(position);
                mPagerAdapter.setPrimaryItem(container, realPosition, object);
            }else{
                super.setPrimaryItem(container,position,object);
            }
        }

        @Override
        public void finishUpdate(ViewGroup container) {
            if(mPagerAdapter!=null)
            {
                mPagerAdapter.finishUpdate(container);
            }else{
                super.finishUpdate(container);
            }
        }

        @Override
        public Parcelable saveState() {
            if(mPagerAdapter!=null)
            {
                return mPagerAdapter.saveState();
            }
            return super.saveState();
        }

        @Override
        public void restoreState(Parcelable state, ClassLoader loader) {
            if(mPagerAdapter!=null) {
                mPagerAdapter.restoreState(state, loader);
            }else{
                super.restoreState(state,loader);
            }

        }

        public void setPagerAdapter(PagerAdapter pagerAdapter) {
            this.mPagerAdapter = pagerAdapter;
        }
    }

    public int getClientWidth(){
        return getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
    }
    private static class OnPagerChangeListener implements ViewPager.OnPageChangeListener{

        private final AutoBannerView mAutoBannerView;

        public OnPagerChangeListener(AutoBannerView autoBannerView) {
            this.mAutoBannerView = autoBannerView;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
            if(shouldCancelHandle()) return;
        }

        @Override
        public void onPageSelected(int position) {
            if(shouldCancelHandle()) return;
              notifyUpdateIndictor(position);
        }

        public void notifyUpdateIndictor(int position) {
            final int realPosition = getRealPosition(position);
            if(this.mAutoBannerView.mOnPagerSelectedListener!=null){
                final PagerAdapter adapter = this.mAutoBannerView.getAdapter();
                final int count = adapter.getCount();

                if(count>1) {
                    this.mAutoBannerView.mOnPagerSelectedListener.onPagerItemSelected(realPosition);
                }else if(count==1){
                    this.mAutoBannerView.mOnPagerSelectedListener.onPagerItemSelected(1);
                }else{
                    this.mAutoBannerView.mOnPagerSelectedListener.onPagerItemSelected(0);
                }
            }
        }

        private int getRealPosition(int position) {
            int realPosition = position;
            if(this.mAutoBannerView .getAdapter().getCount()>1){
                PagerAdapter adapter = this.mAutoBannerView.getAdapter();  //1
                if(adapter instanceof InnerWrapperPagerAdapter){
                    adapter =   ((InnerWrapperPagerAdapter) adapter).getTargetPagerAdapter();
                }
                if(position==0){
                    realPosition = adapter.getCount();
                }else if(position==adapter.getCount()+1){
                    realPosition = 1;
                }
            }
            return realPosition;
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            //在该方法中处理首尾切换,其他方法会产生动画中断问题
            if(shouldCancelHandle()) return;
            if(state!=SCROLL_STATE_IDLE){ //当动画执行完,立即切换
                this.mAutoBannerView.finishResetPosition();
            }

        }

        private boolean shouldCancelHandle() {
            return this.mAutoBannerView==null || mAutoBannerView.getAdapter()==null;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if(lastStateIsPlaying){  //如果之前是轮播的,那么继续轮播
            startPlay();
        }

    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(isPlaying) {
            stopPlay();// 如果从window中移除掉,停止轮播
        }
        onInvisibleToUser();

    }

    private void onInvisibleToUser() {
        final int currentItem = getCurrentItem();
        PagerAdapter adapter = getAdapter();
        if(adapter instanceof InnerWrapperPagerAdapter){
            adapter =   ((InnerWrapperPagerAdapter) adapter).getTargetPagerAdapter();
        }
        if(adapter!=null && adapter.getCount()>1 && currentItem>0) {
            setCurrentItem(currentItem - 1);
            setCurrentItem(currentItem);
        }
    }

    @Override
    protected void onVisibilityChanged(View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        if (visibility == VISIBLE) {
            if(lastStateIsPlaying){  //如果之前是轮播的,那么继续轮播
                startPlay();
            }
        } else if (visibility == INVISIBLE || visibility == GONE) {
            if(isPlaying) {
                stopPlay();// 如果从window中移除掉,停止轮播
            }
            onInvisibleToUser();
        }
    }

    public interface  OnPagerSelectedListener{
        //用于监听真实的滑动位置,方便外部使用
        public void onPagerItemSelected(int position);
    }

    public void startPlay(){
        stopPlay();
        isPlaying = true;
       /* postDelayed(autoRunnable,TIME_WAIT);*/

        mTaskHandler.sendEmptyMessageDelayed(ACTION_PLAY,TIME_WAIT);
    }

    public void stopPlay() {

        lastStateIsPlaying = isPlaying==true;
        isPlaying = false;
        mTaskHandler.removeMessages(ACTION_PLAY);

    }

    @Override
    public boolean handleMessage(Message msg) {
        if(msg==null) return false;
        int action = msg.what;

        switch (action){
            case ACTION_PLAY:
                this.showNext();
                return  true;

        }
        return false;
    }
    private long lastExecuteTimestramp = 0;

    private boolean finishResetPosition() {
        if(!(this.getAdapter() instanceof InnerWrapperPagerAdapter)) return false;
        int currentItem = this.getCurrentItem();
        if(this.getAdapter().getCount()>1){
            InnerWrapperPagerAdapter adapter = (InnerWrapperPagerAdapter) this.getAdapter();
            if(currentItem==0 ){
                //this.setCurrentItem(adapter.getCount()-2,false);
                scrollToItem(adapter.getCount()-2,adapter.getCount());
                return  true;
            }else if(currentItem==adapter.getCount()-1){
                scrollToItem(1,adapter.getCount());
              /*  this.setCurrentItem(1,false)*/;
                return true;
            }
        }
        return false;
    }

    public void showNext() {
        if(Looper.myLooper()!=Looper.getMainLooper()) return; //要求在主线程工作

        final long currentTimestramp = System.currentTimeMillis();
        final long diff = (currentTimestramp - lastExecuteTimestramp);
        lastExecuteTimestramp = currentTimestramp;
        PagerAdapter adapter = this.getAdapter();

        if(null==adapter || adapter.getCount()<=1) return;
        if(!this.isPlaying) return; //停止执行
        int currentItem = this.getCurrentItem();
        if (currentItem > 0 && currentItem < (adapter.getCount() - 1)) {

            if(currentItem==1){
                scrollToItem(1,adapter.getCount());
            }

            this.setCurrentItem(currentItem + 1, true);
        }
        if(diff<AutoBannerView.TIME_WAIT){
            if(mTaskHandler!=null){
                mTaskHandler.removeMessages(ACTION_PLAY);
            }
        }
        if(mTaskHandler!=null)
        {
            mTaskHandler.sendEmptyMessageDelayed(ACTION_PLAY,TIME_WAIT);
        }

    }

    protected void scrollToItem(int target, int  childCount) {
        final int width = getClientWidth();
        int destX = (int) (width * Math.max(-1.0f,
                Math.min(target, childCount)));
        if( getScrollX()!=destX){
            scrollTo(0,0);
            //setCurrentItem存在无法重置scrollX的可能性,最终导致滑动方向不一致,因此这里需要手动设置
        }
        this.setCurrentItem( target, false);
    }

}

三、使用方法

用法很简单我,按照ViewPager的用法即可,但是需要注意的一点是,我们仍然需要进一步封装,因此仅仅依靠自定义的轮播图,可能让人产生误解,因此我们可以进一步封装

public class SlidingBanner extends RelativeLayout implements AutoBannerView.OnPagerSelectedListener {

    private AutoBannerView mAutoPlayViewPager;
    private TextView mPositionTextView;
    private OnPagerItemClickListener onPagerItemClickListener;
    private ImageView.ScaleType scaleType = ImageView.ScaleType.FIT_XY;
    private RotationPageTransformer pageTransformer;
    private int offscreenPageLimit;
    private int pageMargin;

    public SlidingBanner(Context context) {
        this(context,null);
    }

    public SlidingBanner(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SlidingBanner(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ImageView.ScaleType.FIT_XY);
    }

    public void setOnPagerItemClickListener(OnPagerItemClickListener onPagerItemClickListener) {
        this.onPagerItemClickListener = onPagerItemClickListener;
    }

    public void setImageList(List<String> imageList){
        if(imageList==null){
            imageList = new ArrayList<>();
        }
        if( !(mAutoPlayViewPager.getRealAdapter() instanceof SlidingPagerAdapter) ){
            setPagerAdapter(new SlidingPagerAdapter(this, imageList));
        }else{
            SlidingPagerAdapter slidingPagerAdapter = (SlidingPagerAdapter) mAutoPlayViewPager.getRealAdapter();
            slidingPagerAdapter.updateDatasource(imageList);
        }

    }

    public boolean isEmptyBanner(){
        if(mAutoPlayViewPager==null || mAutoPlayViewPager.getRealAdapter()==null){
            return true;
        }
        return false;
    }

    public void hidePositionIndictor(){
        if(mPositionTextView!=null) {
            mPositionTextView.setVisibility(GONE);
        }
    }
    public void showPositionIndictor(){
        if(mPositionTextView!=null) {
            mPositionTextView.setVisibility(VISIBLE);
        }
    }

    public void setPagerAdapter(PagerAdapter pagerAdapter) {
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.setAdapter(pagerAdapter);
        }
    }

    public PagerAdapter getPagerAdapter( ) {
        return mAutoPlayViewPager.getRealAdapter();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        if(mAutoPlayViewPager==null) {
            mAutoPlayViewPager = createAutoPlayViewPager();
            addView(mAutoPlayViewPager,0);
        }
        if(mPositionTextView ==null){
            mPositionTextView = createPositionTextView();
            addView(mPositionTextView,1);
        }
        mAutoPlayViewPager.setOnPagerSelectedListener(this);
    }

    private TextView createPositionTextView() {
        TextView tv = new AppCompatTextView(this.getContext());

        LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp.addRule(ALIGN_PARENT_BOTTOM);
        lp.addRule(ALIGN_PARENT_RIGHT);
        lp.rightMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,8,getResources().getDisplayMetrics());
        lp.bottomMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,4,getResources().getDisplayMetrics());

        PaintDrawable shapeDrawable = new PaintDrawable(0xAA000000);
        shapeDrawable.setCornerRadius(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,8,getResources().getDisplayMetrics()));

        tv.setBackground(shapeDrawable);
        final int px = DisplayUtil.dp2px(getContext(), 8);
        tv.setPadding(px,0,px,0);
        tv.setLayoutParams(lp);
        tv.setTextColor(Color.WHITE);
        tv.setTextSize(12);
        return  tv;
    }

    private AutoBannerView createAutoPlayViewPager() {
        AutoBannerView autoPlayViewPager = new AutoBannerView(getContext());
        LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        autoPlayViewPager.setLayoutParams(lp);
        if(this.pageTransformer!=null){
            autoPlayViewPager.setPageTransformer(true,this.pageTransformer);
        }
        if(this.offscreenPageLimit!=0){
            autoPlayViewPager.setOffscreenPageLimit(this.offscreenPageLimit);
        }
        autoPlayViewPager.setPageMargin(this.pageMargin);
        return autoPlayViewPager;
    }

    @Override
    public void onPagerItemSelected(int position) {
        if(mAutoPlayViewPager==null || mAutoPlayViewPager.getRealAdapter()==null) return;
        final PagerAdapter adapter = mAutoPlayViewPager.getRealAdapter();

        updateIndictor(position,adapter.getCount());
    }

    private void updateIndictor(int position,int count) {
        if(mPositionTextView==null) return;
        mPositionTextView.setText(String.format("%s/%s",position,count));
    }

    public ImageView.ScaleType getScaleType() {
        return scaleType;
    }

    public void setScaleType(ImageView.ScaleType scaleType) {
        this.scaleType = scaleType;
    }

    public void startPlay() {
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.startPlay();
        }
    }

    public void stopPlay(){
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.stopPlay();
        }
    }

    public void setPageTransformer(RotationPageTransformer pageTransformer) {
        this.pageTransformer = pageTransformer;
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.setPageTransformer(true,pageTransformer);
        }
    }

    public void setOffscreenPageLimit(int offscreenPageLimit) {
        this.offscreenPageLimit = offscreenPageLimit;
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.setOffscreenPageLimit(this.offscreenPageLimit);
        }
    }

    public void setPageMargin(int pageMargin) {
        this.pageMargin = pageMargin;
        if(mAutoPlayViewPager!=null){
            mAutoPlayViewPager.setPageMargin(20);
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
       // notifyImageViewInvalidate();

    }

    private void notifyImageViewInvalidate() {
        if(mAutoPlayViewPager==null) return;
        final List<ImageView> imageViews = AppUtils.getViews(mAutoPlayViewPager, ImageView.class);
        if(imageViews==null || imageViews.size()==0) return;
        for (ImageView imageView : imageViews){
            if(imageView==null || imageView.getVisibility()==GONE) continue;
            final Drawable drawable = imageView.getDrawable();
            if(drawable==null){
                imageView.setImageResource(R.drawable.defualt_img);
            }else {
                if (!drawable.isVisible()) {
                    drawable.setVisible(true, false);
                }else {
                    drawable.invalidateSelf();
                }
            }
        }
    }

    public final static  class  SlidingPagerAdapter  extends PagerAdapter{

        private final SlidingBanner slidingBanner;
        private List<String>  imagelst;

        public SlidingPagerAdapter(SlidingBanner slidingBanner, List<String>  images){
            this.slidingBanner = slidingBanner;
            this.imagelst = new ArrayList<>();
            this.imagelst.addAll(images);

        }

        @Override
        public void startUpdate(ViewGroup container) {
            super.startUpdate(container);
            container.setEnabled(false);
        }

        @Override
        public void finishUpdate(ViewGroup container) {
            super.finishUpdate(container);
            container.requestLayout();
            container.invalidate();
            container.setEnabled(true);
        }

        @Override
        public int getItemPosition(Object object) {
            return PagerAdapter.POSITION_NONE;
        }

        @Override
        public int getCount() {
            return imagelst.size();
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view==object;
        }
        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = getView(container, position);
            if(view.getParent()!= null){
                final ViewGroup parent = ((ViewGroup)view.getParent());
                parent.removeViewInLayout(view);
            }
            if(container instanceof AutoBannerView) {
                ((AutoBannerView) container).addViewInLayout(view,-1,view.getLayoutParams());
            }else{
                container.addView(view);
            }
            addOnClickListenerToView(view,position,container);
            return view;
        }

        private void addOnClickListenerToView(View view,int position ,ViewGroup container) {

            view.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    int childIndex = position;
                    if(slidingBanner.onPagerItemClickListener!=null) {
                        slidingBanner.onPagerItemClickListener.onPagerItemClick(childIndex,view,container);
                    }
                }
            });
        }

        private View getView(ViewGroup container,int position){

            final LayoutInflater inflater = LayoutInflater.from(container.getContext());
            final ImageView view = getImageView(inflater, position);
           Glide.with(view).diskCacheStrategy(DiskCacheStrategy.ALL).load(imagelst.get(position)).placeholder(R.drawable.xsj_default_product_img).into(view);
            return  view;
        }

        private ImageView getImageView(LayoutInflater inflater, int position) {
            ImageView imageView = new AppImageView(inflater.getContext());
            imageView.setImageResource(R.drawable.xsj_default_product_img);
            ViewPager.LayoutParams lp = new ViewPager.LayoutParams();
            imageView.setLayoutParams(lp);
            if(slidingBanner.getScaleType()!=null){
                imageView.setScaleType(slidingBanner.getScaleType());
            }
            return imageView;
        }

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

        public void updateDatasource(List<String> imageDataset) {
            if(imageDataset==null || imageDataset.size()==0){
                if(this.imagelst.size()>0){
                    this.imagelst.clear();
                    notifyDataSetChanged();
                }
                return;
            }
            if(this.imagelst.size()!=imageDataset.size()){
                this.imagelst.clear();
                this.imagelst.addAll(imageDataset);
                notifyDataSetChanged();
                return;
            }
            boolean isNeedUpdate = false;
            for (int i=0;i<this.imagelst.size();i++){
                final String oldUrl = imagelst.get(i);
                final String newUrl = imageDataset.get(i);
                if(!TextUtils.equals(oldUrl,newUrl)){
                    isNeedUpdate = true;
                    break;
                }
            }

            if(isNeedUpdate){
                this.imagelst.clear();
                this.imagelst.addAll(imageDataset);
                notifyDataSetChanged();
            }

        }

    }

     public  interface  OnPagerItemClickListener{  //暴露点击事件
          public void  onPagerItemClick(int position, View view, ViewGroup viewPager);
    }
}

使用方法:

      slidingBanner.setImageList(entity);
        slidingBanner.setOnPagerItemClickListener(this);
        slidingBanner.startPlay();

原文地址:https://blog.51cto.com/14295695/2399718

时间: 2024-10-12 06:19:40

Android ViewPager实现循环轮播图的相关文章

android ViewPager实现的轮播图广告自定义视图,网络获取图片和数据

public class SlideShowAdView extends FrameLayout { //轮播图图片数量    private static int IMAGE_COUNT = 3;    //自动轮播的时间间隔    private final static int TIME_INTERVAL = 5;    //自动轮播启用开关    private final static boolean isAutoPlay = false;       //自定义轮播图的资源ID   

非常简单的方法实现ViewPager自动循环轮播

非常简单的方法实现ViewPager自动循环轮播,见红色代码部分,其它的代码可以忽略不看. 简洁高效是我解决问题的首要出发点. package com.shuivy.happylendandreadbooks.fragment; import android.app.Activity; import android.app.Fragment; import android.os.Bundle; import android.os.Handler; import android.support.v

iOS: 无限循环轮播图简单封装

轮播图思路: 1.首先要有一个ScrollView和两张图片,把图片放到ScrollView上. 2.要想滚动ScrollView的宽度需设置屏宽的2倍. 3.循环滚动,当滚动到最后一张图片时,采用偏移的方法,将偏移量归零,回到第一张图片. 4.将第二张的图片上的所有值赋给第一张图片. 5.设置让它自己滚动,需添加定时器. 需要的第三方数据库:SDWebImage m.文件内: #imporst "ScrollView.h" @interface ScrollView ()<UI

JS-特效 ~ 01. 事件对象、offset偏移/检测、无缝滚动、自动循环轮播图

Math.round ( ) :正书四舍五入,负数五舍六入 用定时器,先清除定时器 事件对象 event event:事件被触动时,鼠标和键盘的状态,通过属性控制 Offset:偏移,检测 1. 获取元素尺寸 2. 检测盒子的宽高     事件源.offsetLeft. /. ele.offsetWidth /返回的数值没有单位,是number类型 /包括内边距.边框,不包括外边距 3. 获取定位的元素的left和top值  offsetLeft / offsetTop 如果被获取的元素没有定位

Android侧滑菜单和轮播图之滑动冲突

接手一个项目,有一个问题需要修改:轮播图不能手动滑动,手动滑动轮播图只会触发侧滑菜单. 猜测:viewpager控件(轮播图)的触摸事件被SlidingMenu控件(侧滑菜单,非第三方项目,乃是上个开发人员自定义的)拦截了. 基于这个猜测,我自定义一个ViewPager,重写dispatchTouchEvent.onInterceptTouchEvent和onTouchEvent,分别在这三个方法中打印log: 重写SlidingMenu的dispatchTouchEvent.onInterce

无限循环轮播图之JS部分(原生JS)

JS逻辑与框架调用 1 <script type="text/javascript"> 2 var oBox = document.getElementById('box'); 3 var oPrev = document.getElementById('prev'); 4 var oNext = document.getElementById('next'); 5 var oUl = oBox.children[0]; 6 var aLi = oUl.children;

无限循环轮播图之运动框架(原生JS)

封装运动框架 1 function getStyle(obj,name){ 2 if(obj.currentStyle){ 3 return obj.currentStyle[name]; 4 }else{ 5 return getComputedStyle(obj,false)[name]; 6 } 7 } 8 function move(obj,json,options){ 9 var options=options || {}; 10 var duration=options.durati

Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面布局实现如下: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android&

Android轮播图封装,下拉刷新相结合

自定义轮播图CarouselView 自定义下拉刷新PullRefreshListView 马上就要正式做毕业设计了,一些零碎时间写其中的一个模块,现记录下来,以备以后忘记时使用.欢迎大神不吝纠正. 效果图: layout_carousel.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com