d0e1f 发表于 2015-07-10 13:24

让ViewPager循环起来

自定义ViewPage,支持循环滚动,并在此基础上提供一个图片轮播控件的实现。

演示代码:http://download.csdn.net/detail/u012070340/8884565

Java代码import android.content.Context;
import android.os.Handler;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

/**
* Cycle 循环
*/
public class CycleViewPager extends ViewPager {


    private PagerAdapter adapter = new PagerAdapter() {
         
      private View cachedHeader, cachedBottom; /* 缓存相关 */
         
      public Object instantiateItem(ViewGroup container, int position) {

            View v = null;
            if(enabled()) { /* 缓存相关 */
                if(position == 1){
                  if(cachedHeader != null && container.indexOfChild(cachedHeader) == -1){
                        v = cachedHeader;
                  }
                  if(cachedBottom == null || container.indexOfChild(cachedBottom) != -1){
                        cachedBottom = (View) adapter2.instantiateItem(container, adapter2.getCount() - 1);
                  }
                }else if(position == getCount() - 2){
                  if(cachedBottom != null && container.indexOfChild(cachedBottom) == -1){
                        v = cachedBottom;
                  }
                  if(cachedHeader == null || container.indexOfChild(cachedHeader) != -1){
                        cachedHeader = (View) adapter2.instantiateItem(container, 0);
                  }
                }
            }
            
            if(v == null){
                v = (View) adapter2.instantiateItem(container, convert(position));
            }
            container.addView(v); // 用户适配器仅负责实例化即可
            return v;
      }
         
      @Override
      public boolean isViewFromObject(View arg0, Object arg1) {
            return arg0 == arg1;
      }
         
      public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView((View) object);
      }
         
      public int getItemPosition(Object object) {
            return adapter2.getItemPosition(object); // 动态更新
      }
         
      public void setPrimaryItem(ViewGroup container, int position, Object object) {
            if(!edge(position))
                adapter2.setPrimaryItem(container, convert(position), object);
      }
         
      @Override
      public int getCount() {
            return enabled() ? adapter2.getCount() + 2 : adapter2 != null ? adapter2.getCount() : 0;
      }
         
    }, adapter2;
   

    private OnPageChangeListener listener = new OnPageChangeListener() {
         
      Handler handler = new Handler();
         
      @Override
      public void onPageSelected(int position) {
            if(listener2 != null && !edge(position))
                listener2.onPageSelected(convert(position));
      }
         
      @Override
      public void onPageScrolled(final int position, final float percent, int offsetPx) {
            if(listener2 != null && !edge(position))
                listener2.onPageScrolled(convert(position), percent, offsetPx);
            
            if(enabled() && percent == 0){
                handler.postDelayed(new Runnable() {
                     
                  @Override
                  public void run() {
                        
                        if(position == 0)
                            CycleViewPager.super.setCurrentItem(( adapter.getCount() - 2 ) % adapter.getCount(), false); // 切到倒数第二页
                        else if(position == adapter.getCount() - 1)
                            CycleViewPager.super.setCurrentItem(1, false); // 切到正数第二页
                  }
                }, 30); // 延迟切换,避免闪烁
            }
      }
         
      @Override
      public void onPageScrollStateChanged(int state) {
            if(listener2 != null && !edge(CycleViewPager.super.getCurrentItem()))
                listener2.onPageScrollStateChanged(state);
      }
         
    }, listener2;
   
    public CycleViewPager(Context context, AttributeSet attrs) {
      super(context, attrs);
      init();
    }

    public CycleViewPager(Context context) {
      super(context);
      init();
    }
   
    private void init() {
      super.setAdapter(adapter);
      super.setOnPageChangeListener(listener);
    }
   
    @Override
    public void setAdapter(PagerAdapter adapter) {
      this.adapter2 = adapter;
      if(enabled())
            super.setCurrentItem(1);
      this.adapter.notifyDataSetChanged();
    }
   
    @Override
    public void setOnPageChangeListener(OnPageChangeListener listener) {
      this.listener2 = listener;
    }

    @Override
    public void setCurrentItem(int item) {
      super.setCurrentItem(enabled() ? item + 1 : item);
    }
   
    @Override
    public void setCurrentItem(int item, boolean smoothScroll) {
      super.setCurrentItem(enabled() ? item + 1 : item, smoothScroll);
    }
   
    @Override
    public int getCurrentItem() {
      return convert(super.getCurrentItem());
    }
   
    private int convert(int item){
      return enabled() ? item == 0 ? adapter2.getCount() - 1 : ( item > adapter2.getCount() ? 0 : item - 1 ): item;
    }
   
    private boolean enabled(){
      return adapter2 != null ? adapter2.getCount() > 1 : false;
    }
   
    private boolean edge(int position){
      return enabled() ? position == 0 || position == adapter.getCount() - 1 : false;
    }
}基于此实现的图片轮播控件import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.PagerAdapter;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

public class ImagePager extends CycleViewPager {

    private int[] resIds;
   
    private PagerAdapter adapter = new PagerAdapter(){

      @Override
      public Object instantiateItem(ViewGroup container, int position) {
            ImageView iv = new ImageView(getContext());
            iv.setImageResource(resIds);
            iv.setScaleType(ImageView.ScaleType.FIT_XY);
            return iv;
      }
         
      @Override
      public int getCount() {
            return resIds == null ? 0 : resIds.length;
      }

      @Override
      public boolean isViewFromObject(View arg0, Object arg1) {
            return false;
      }
    };
   
    private OnPageChangeListener listener = new OnPageChangeListener(){

      @Override
      public void onPageScrollStateChanged(int arg0) {
            if(listener2 != null){
                listener2.onPageScrollStateChanged(arg0);
            }
            
            switch (arg0) {
            case SCROLL_STATE_IDLE: // 闲置
                if(!handler.hasMessages(START_FLIPPING))
                  handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);// 延时滚动
                break;
            case SCROLL_STATE_DRAGGING: // 拖动中
                handler.sendEmptyMessage(STOP_FLIPPING); // 取消滚动
                break;
            case SCROLL_STATE_SETTLING: // 拖动结束
                break;
            }
      }

      @Override
      public void onPageScrolled(int arg0, float arg1, int arg2) {
            if(listener2 != null){
                listener2.onPageScrolled(arg0, arg1, arg2);
            }
      }

      @Override
      public void onPageSelected(int arg0) {
            if(listener2 != null){
                listener2.onPageSelected(arg0);
            }
      }
    }, listener2;

    private final int START_FLIPPING = 0;
    private final int STOP_FLIPPING = 1;
   
    private Handler handler = new Handler(){
         
      public void handleMessage(Message msg) {
            
            switch (msg.what) {
            case START_FLIPPING:
                setCurrentItem(getCurrentItem() + 1);
                handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);// 延时滚动
                break;
            case STOP_FLIPPING:
                handler.removeMessages(START_FLIPPING);
                break;
            }
      }
    };
   
    public ImagePager(Context context, AttributeSet attrs) {
      super(context, attrs);
      init();
    }

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

    private void init(){
         
      setOffscreenPageLimit(1); // 最大页面缓存数量
         
      super.setOnPageChangeListener(listener);

      handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);// 自动滚动
    }
   
    public void setViews(int[] ids){
      this.resIds = ids;
      setAdapter(adapter);
    }

    @Override
    public void setOnPageChangeListener(OnPageChangeListener listener) {
      this.listener2 = listener;
    }
}

baopbird2005 发表于 2015-07-15 11:30

Android 的应用

renxiao2003 发表于 2015-08-12 13:07

自动循环吗?
页: [1]
查看完整版本: 让ViewPager循环起来