免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4767 | 回复: 2
打印 上一主题 下一主题

让ViewPager循环起来 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-07-10 13:24 |只看该作者 |倒序浏览
自定义ViewPage,支持循环滚动,并在此基础上提供一个图片轮播控件的实现。

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

Java代码
  1. import android.content.Context;
  2. import android.os.Handler;
  3. import android.support.v4.view.PagerAdapter;
  4. import android.support.v4.view.ViewPager;
  5. import android.util.AttributeSet;
  6. import android.view.View;
  7. import android.view.ViewGroup;

  8. /**
  9. * Cycle 循环
  10. */
  11. public class CycleViewPager extends ViewPager {


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

  17.             View v = null;
  18.             if(enabled()) { /* 缓存相关 */
  19.                 if(position == 1){
  20.                     if(cachedHeader != null && container.indexOfChild(cachedHeader) == -1){
  21.                         v = cachedHeader;
  22.                     }
  23.                     if(cachedBottom == null || container.indexOfChild(cachedBottom) != -1){
  24.                         cachedBottom = (View) adapter2.instantiateItem(container, adapter2.getCount() - 1);
  25.                     }
  26.                 }else if(position == getCount() - 2){
  27.                     if(cachedBottom != null && container.indexOfChild(cachedBottom) == -1){
  28.                         v = cachedBottom;
  29.                     }
  30.                     if(cachedHeader == null || container.indexOfChild(cachedHeader) != -1){
  31.                         cachedHeader = (View) adapter2.instantiateItem(container, 0);
  32.                     }
  33.                 }
  34.             }
  35.             
  36.             if(v == null){
  37.                 v = (View) adapter2.instantiateItem(container, convert(position));
  38.             }
  39.             container.addView(v); // 用户适配器仅负责实例化即可
  40.             return v;
  41.         }
  42.          
  43.         @Override
  44.         public boolean isViewFromObject(View arg0, Object arg1) {
  45.             return arg0 == arg1;
  46.         }
  47.          
  48.         public void destroyItem(ViewGroup container, int position, Object object) {
  49.             container.removeView((View) object);
  50.         }
  51.          
  52.         public int getItemPosition(Object object) {
  53.             return adapter2.getItemPosition(object); // 动态更新
  54.         }
  55.          
  56.         public void setPrimaryItem(ViewGroup container, int position, Object object) {
  57.             if(!edge(position))
  58.                 adapter2.setPrimaryItem(container, convert(position), object);
  59.         }
  60.          
  61.         @Override
  62.         public int getCount() {
  63.             return enabled() ? adapter2.getCount() + 2 : adapter2 != null ? adapter2.getCount() : 0;
  64.         }
  65.          
  66.     }, adapter2;
  67.      

  68.     private OnPageChangeListener listener = new OnPageChangeListener() {
  69.          
  70.         Handler handler = new Handler();
  71.          
  72.         @Override
  73.         public void onPageSelected(int position) {
  74.             if(listener2 != null && !edge(position))
  75.                 listener2.onPageSelected(convert(position));
  76.         }
  77.          
  78.         @Override
  79.         public void onPageScrolled(final int position, final float percent, int offsetPx) {
  80.             if(listener2 != null && !edge(position))
  81.                 listener2.onPageScrolled(convert(position), percent, offsetPx);
  82.             
  83.             if(enabled() && percent == 0){
  84.                 handler.postDelayed(new Runnable() {
  85.                      
  86.                     @Override
  87.                     public void run() {
  88.                         
  89.                         if(position == 0)
  90.                             CycleViewPager.super.setCurrentItem(( adapter.getCount() - 2 ) % adapter.getCount(), false); // 切到倒数第二页
  91.                         else if(position == adapter.getCount() - 1)
  92.                             CycleViewPager.super.setCurrentItem(1, false); // 切到正数第二页
  93.                     }
  94.                 }, 30); // 延迟切换,避免闪烁
  95.             }
  96.         }
  97.          
  98.         @Override
  99.         public void onPageScrollStateChanged(int state) {
  100.             if(listener2 != null && !edge(CycleViewPager.super.getCurrentItem()))
  101.                 listener2.onPageScrollStateChanged(state);
  102.         }
  103.          
  104.     }, listener2;
  105.      
  106.     public CycleViewPager(Context context, AttributeSet attrs) {
  107.         super(context, attrs);
  108.         init();
  109.     }

  110.     public CycleViewPager(Context context) {
  111.         super(context);
  112.         init();
  113.     }
  114.      
  115.     private void init() {
  116.         super.setAdapter(adapter);
  117.         super.setOnPageChangeListener(listener);
  118.     }
  119.      
  120.     @Override
  121.     public void setAdapter(PagerAdapter adapter) {
  122.         this.adapter2 = adapter;
  123.         if(enabled())
  124.             super.setCurrentItem(1);
  125.         this.adapter.notifyDataSetChanged();
  126.     }
  127.      
  128.     @Override
  129.     public void setOnPageChangeListener(OnPageChangeListener listener) {
  130.         this.listener2 = listener;
  131.     }

  132.     @Override
  133.     public void setCurrentItem(int item) {
  134.         super.setCurrentItem(enabled() ? item + 1 : item);
  135.     }
  136.      
  137.     @Override
  138.     public void setCurrentItem(int item, boolean smoothScroll) {
  139.         super.setCurrentItem(enabled() ? item + 1 : item, smoothScroll);
  140.     }
  141.      
  142.     @Override
  143.     public int getCurrentItem() {
  144.         return convert(super.getCurrentItem());
  145.     }
  146.      
  147.     private int convert(int item){
  148.         return enabled() ? item == 0 ? adapter2.getCount() - 1 : ( item > adapter2.getCount() ? 0 : item - 1 ): item;
  149.     }
  150.      
  151.     private boolean enabled(){
  152.         return adapter2 != null ? adapter2.getCount() > 1 : false;
  153.     }
  154.      
  155.     private boolean edge(int position){
  156.         return enabled() ? position == 0 || position == adapter.getCount() - 1 : false;
  157.     }
  158. }
复制代码
基于此实现的图片轮播控件
  1. import android.content.Context;
  2. import android.os.Handler;
  3. import android.os.Message;
  4. import android.support.v4.view.PagerAdapter;
  5. import android.util.AttributeSet;
  6. import android.view.View;
  7. import android.view.ViewGroup;
  8. import android.widget.ImageView;

  9. public class ImagePager extends CycleViewPager {

  10.     private int[] resIds;
  11.      
  12.     private PagerAdapter adapter = new PagerAdapter(){

  13.         @Override
  14.         public Object instantiateItem(ViewGroup container, int position) {
  15.             ImageView iv = new ImageView(getContext());
  16.             iv.setImageResource(resIds[position]);
  17.             iv.setScaleType(ImageView.ScaleType.FIT_XY);
  18.             return iv;
  19.         }
  20.          
  21.         @Override
  22.         public int getCount() {
  23.             return resIds == null ? 0 : resIds.length;
  24.         }

  25.         @Override
  26.         public boolean isViewFromObject(View arg0, Object arg1) {
  27.             return false;
  28.         }
  29.     };
  30.      
  31.     private OnPageChangeListener listener = new OnPageChangeListener(){

  32.         @Override
  33.         public void onPageScrollStateChanged(int arg0) {
  34.             if(listener2 != null){
  35.                 listener2.onPageScrollStateChanged(arg0);
  36.             }
  37.             
  38.             switch (arg0) {
  39.             case SCROLL_STATE_IDLE: // 闲置
  40.                 if(!handler.hasMessages(START_FLIPPING))
  41.                     handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);  // 延时滚动
  42.                 break;
  43.             case SCROLL_STATE_DRAGGING: // 拖动中
  44.                 handler.sendEmptyMessage(STOP_FLIPPING); // 取消滚动
  45.                 break;
  46.             case SCROLL_STATE_SETTLING: // 拖动结束
  47.                 break;
  48.             }
  49.         }

  50.         @Override
  51.         public void onPageScrolled(int arg0, float arg1, int arg2) {
  52.             if(listener2 != null){
  53.                 listener2.onPageScrolled(arg0, arg1, arg2);
  54.             }
  55.         }

  56.         @Override
  57.         public void onPageSelected(int arg0) {
  58.             if(listener2 != null){
  59.                 listener2.onPageSelected(arg0);
  60.             }
  61.         }
  62.     }, listener2;

  63.     private final int START_FLIPPING = 0;
  64.     private final int STOP_FLIPPING = 1;
  65.      
  66.     private Handler handler = new Handler(){
  67.          
  68.         public void handleMessage(Message msg) {
  69.             
  70.             switch (msg.what) {
  71.             case START_FLIPPING:
  72.                 setCurrentItem(getCurrentItem() + 1);
  73.                 handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);  // 延时滚动
  74.                 break;
  75.             case STOP_FLIPPING:
  76.                 handler.removeMessages(START_FLIPPING);
  77.                 break;
  78.             }
  79.         }
  80.     };
  81.      
  82.     public ImagePager(Context context, AttributeSet attrs) {
  83.         super(context, attrs);
  84.         init();
  85.     }

  86.     public ImagePager(Context context) {
  87.         super(context);
  88.         init();
  89.     }

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

  95.         handler.sendEmptyMessageDelayed(START_FLIPPING, 3000);  // 自动滚动
  96.     }
  97.      
  98.     public void setViews(int[] ids){
  99.         this.resIds = ids;
  100.         setAdapter(adapter);
  101.     }

  102.     @Override
  103.     public void setOnPageChangeListener(OnPageChangeListener listener) {
  104.         this.listener2 = listener;
  105.     }
  106. }
复制代码

论坛徽章:
80
20周年集字徽章-庆
日期:2020-10-28 14:09:1215-16赛季CBA联赛之北京
日期:2020-10-28 13:32:5315-16赛季CBA联赛之北控
日期:2020-10-28 13:32:4815-16赛季CBA联赛之天津
日期:2020-10-28 13:13:35黑曼巴
日期:2020-10-28 12:29:1520周年集字徽章-周	
日期:2020-10-31 15:10:0720周年集字徽章-20	
日期:2020-10-31 15:10:07ChinaUnix元老
日期:2015-09-29 11:56:3020周年集字徽章-年
日期:2020-10-28 14:14:56
2 [报告]
发表于 2015-07-15 11:30 |只看该作者
Android 的应用

论坛徽章:
59
2015七夕节徽章
日期:2015-08-24 11:17:25ChinaUnix专家徽章
日期:2015-07-20 09:19:30每周论坛发贴之星
日期:2015-07-20 09:19:42ChinaUnix元老
日期:2015-07-20 11:04:38荣誉版主
日期:2015-07-20 11:05:19巳蛇
日期:2015-07-20 11:05:26CU十二周年纪念徽章
日期:2015-07-20 11:05:27IT运维版块每日发帖之星
日期:2015-07-20 11:05:34操作系统版块每日发帖之星
日期:2015-07-20 11:05:36程序设计版块每日发帖之星
日期:2015-07-20 11:05:40数据库技术版块每日发帖之星
日期:2015-07-20 11:05:432015年辞旧岁徽章
日期:2015-07-20 11:05:44
3 [报告]
发表于 2015-08-12 13:07 |只看该作者
自动循环吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP