一. 默认不可以无限循环的状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 public  class  MainActivity  extends  AppCompatActivity           private  int [] resources = {R.drawable.pic_1,R.drawable.pic_2,R.drawable.pic_3};     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  ViewPager viewPager = findViewById(R.id.pager);                  viewPager.setOffscreenPageLimit(resources.length);                  viewPager.setAdapter(new  PagerAdapter() {             @Override              public  int  getCount ()                   return  resources.length;             }             @Override              public  boolean  isViewFromObject (@NonNull  View view, @NonNull  Object object)                   return  object == view;             }             @NonNull              @Override              public  Object instantiateItem (@NonNull  ViewGroup container, int  position)                                    View inflate = LayoutInflater.from(getApplicationContext()).inflate(R.layout.pager_layout, null );                 ImageView imageView = inflate.findViewById(R.id.image_view);                 imageView.setBackgroundResource(resources[position]);                                  container.addView(inflate);                 return  inflate;             }             @Override              public  void  destroyItem (@NonNull  ViewGroup container, int  position, @NonNull  Object object)                   container.removeView((View) object);             }         });     } } <!-- activity_main.xml ---> <?xml version="1.0"  encoding="utf-8" ?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      xmlns:app="http://schemas.android.com/apk/res-auto"      xmlns:tools="http://schemas.android.com/tools"      android:layout_width="match_parent"      android:layout_height="match_parent"      tools:context=".MainActivity"      android:orientation="vertical" >     <androidx.viewpager.widget.ViewPager         android:id="@+id/pager"          android:layout_width="match_parent"          android:layout_height="wrap_content"          android:layout_marginTop="100dp"          android:clipChildren="false"          /> </LinearLayout>            <!-- pager_layout.xml --> <?xml version="1.0"  encoding="utf-8" ?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="wrap_content" >     <ImageView         android:id="@+id/image_view"          android:layout_width="match_parent"          android:layout_height="wrap_content"          /> </LinearLayout> 
二.  伪无限循环 如果我们设置 ViewPager 的 页面数量很大,然后在 初始化页面 的函数中对 postion 取余。这就相当于我们创建了很多的一模一样的页面连续的排列在一起,这样向右滑动就会形成无限滑动的效果。虽然,理论上一直向右滑动还是会滑不动,但是一般情况下是不会这么无聊的。
这样还有一个问题,向左滑动还是不能滑动的。但是,如果我们将初始页面设置在中间位置,那么就可以达到无限滑动的效果了。
① 设置步骤:
在 PagerAdapter的getCount 方法中设置 返回值 是一个很大的值。 
在 PagerAdapter的instantiateItem 方法中对 position 进行取余操作,一方面是防止数组越界,一方面是为了显示正确的内容。 
使用 setCurrentItem 方法,设置 显示的页面 大概处于中间的位置。注意该方法一定要在设置 适配器 之后再调用,否则会没有效果。 
 
② 返回很大的页面会不会影响内存?
我个人觉得,ViewPager默认只会加载两个页面,滑动了之后,还是只加载两个页面,不会对内存造成太大的影响。
参考文章:Android ViewPager 无限轮播Integer.MAX_VALUE 争议(看源码) 
③ 在 getCount 方法中 返回 Integer.MAX_VALUE 的问题?
使用Integer.MAX_VALUE会在setCurrentItem()的时候发生ANR,所以还是设置为一个比较大的数比较好。
④ 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public  class  MainActivity  extends  AppCompatActivity           private  int [] resources = {R.drawable.pic_1,R.drawable.pic_2,R.drawable.pic_3};     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  ViewPager viewPager = findViewById(R.id.pager);                                    viewPager.setAdapter(new  PagerAdapter() {             @Override              public  int  getCount ()                   if  (resources.length == 1 ){                     return  1 ;                 }                 return  500 ;             }             @Override              public  boolean  isViewFromObject (@NonNull  View view, @NonNull  Object object)                   return  object == view;             }             @NonNull              @Override              public  Object instantiateItem (@NonNull  ViewGroup container, int  position)                                    int  realPosition = position % resources.length;                                  View inflate = LayoutInflater.from(getApplicationContext()).inflate(R.layout.pager_layout, null );                 ImageView imageView = inflate.findViewById(R.id.image_view);                 imageView.setBackgroundResource(resources[realPosition]);                                  container.addView(inflate);                 return  inflate;             }             @Override              public  void  destroyItem (@NonNull  ViewGroup container, int  position, @NonNull  Object object)                   container.removeView((View) object);             }         });                  viewPager.setCurrentItem(240 );     } } 
⑤ 运行效果
三. 真正的无限循环 假设有三条页面数据,分别是0、1、2。我们再创建一个新的页面数据,长度为真实数据的长度+2,在最前面插入最后一条页面数据2,在最后面插入第一条页面数据0,新的页面数据就变为2、0、1、2、0。设置新的页面数据为ViewPager的数据时,需要注意,设置默认开始的页面是第一个页面0。
当ViewPager滑动到最后一个页面0时就通过setCurrentItem(int item,boolean smoothScroll)方法将页面切换到第一个页面0处。同理当滑动到第一个页面2时,通过该方法将页面切换到第二个页面2,这样给我们的感觉就是无限循环。
① 操作步骤
在 PagerAdapter的getCount 方法中设置 返回值 是想要显示的页面数量 + 2。 
在 PagerAdapter的instantiateItem 方法中对 position 进行相关判断更改,以显示正确的内容。 
使用 setCurrentItem 方法,设置 显示的页面 是 第二个 页面。 
通过在监听滚动方法的 onPageSelected 判断有没有滑动到左右添加的两个页面,如果滑到到了,需要使用 setCurrentItem 移动到该页面对应的真正页面处。 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 public  class  MainActivity  extends  AppCompatActivity           private  int [] resources = {R.drawable.pic_1,R.drawable.pic_2,R.drawable.pic_3};     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  final  ViewPager viewPager = findViewById(R.id.pager);                                    viewPager.setAdapter(new  PagerAdapter() {             @Override              public  int  getCount ()                   return  resources.length + 2 ;             }             @Override              public  boolean  isViewFromObject (@NonNull  View view, @NonNull  Object object)                   return  object == view;             }             @NonNull              @Override              public  Object instantiateItem (@NonNull  ViewGroup container, int  position)                                    int  realPosition;                                                                                     if  (position == 0 ) {                                                               realPosition = resources.length - 1 ;                 } else  if  (position == resources.length + 2  - 1 ) {                                                               realPosition = 0 ;                 } else  {                     realPosition = position - 1 ;                 }                                  View inflate = LayoutInflater.from(getApplicationContext()).inflate(R.layout.pager_layout, null );                 ImageView imageView = inflate.findViewById(R.id.image_view);                 imageView.setBackgroundResource(resources[realPosition]);                                  container.addView(inflate);                 return  inflate;             }             @Override              public  void  destroyItem (@NonNull  ViewGroup container, int  position, @NonNull  Object object)                   container.removeView((View) object);             }         });                  viewPager.setCurrentItem(1 );                  viewPager.addOnPageChangeListener(new  ViewPager.OnPageChangeListener() {             @Override              public  void  onPageScrolled (int  position, float  positionOffset, int  positionOffsetPixels)               }                                                                 @Override              public  void  onPageSelected (int  position)                   if  (position == 0 ){                                          viewPager.setCurrentItem(resources.length,false );                 }else  if  (position == resources.length+1 ){                                          viewPager.setCurrentItem(1 ,false );                 }             }             @Override              public  void  onPageScrollStateChanged (int  state)               }         });     } } 
② 运行效果
③ 上面移动位置的操作是在 onPageSelected 方法中执行,该方法是已经滑动到该页面后才开始调用,我们可以看到有一点点的生硬。如果我们放在 onPageScrollStateChanged 方法中 滑动结束的时候移动位置就看不到生硬的效果了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 public  class  MainActivity  extends  AppCompatActivity           private  int [] resources = {R.drawable.pic_1,R.drawable.pic_2,R.drawable.pic_3};     @Override      protected  void  onCreate (Bundle savedInstanceState)           super .onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  final  ViewPager viewPager = findViewById(R.id.pager);                                    viewPager.setAdapter(new  PagerAdapter() {             @Override              public  int  getCount ()                   return  resources.length + 2 ;             }             @Override              public  boolean  isViewFromObject (@NonNull  View view, @NonNull  Object object)                   return  object == view;             }             @NonNull              @Override              public  Object instantiateItem (@NonNull  ViewGroup container, int  position)                                    int  realPosition;                                                                                     if  (position == 0 ) {                                                               realPosition = resources.length - 1 ;                 } else  if  (position == resources.length + 2  - 1 ) {                                                               realPosition = 0 ;                 } else  {                     realPosition = position - 1 ;                 }                                  View inflate = LayoutInflater.from(getApplicationContext()).inflate(R.layout.pager_layout, null );                 ImageView imageView = inflate.findViewById(R.id.image_view);                 imageView.setBackgroundResource(resources[realPosition]);                                  container.addView(inflate);                 return  inflate;             }             @Override              public  void  destroyItem (@NonNull  ViewGroup container, int  position, @NonNull  Object object)                   container.removeView((View) object);             }         });                  viewPager.setCurrentItem(1 );                  viewPager.addOnPageChangeListener(new  ViewPager.OnPageChangeListener() {                          int  currentPosition = 0 ;             @Override              public  void  onPageScrolled (int  position, float  positionOffset, int  positionOffsetPixels)               }                          @Override              public  void  onPageSelected (int  position)                   currentPosition = position;             }             @Override              public  void  onPageScrollStateChanged (int  state)                                    if  (state == ViewPager.SCROLL_STATE_IDLE){                                                                                                         if  (currentPosition == 0 ){                                                  viewPager.setCurrentItem(resources.length,false );                     }else  if  (currentPosition == resources.length+1 ){                                                  viewPager.setCurrentItem(1 ,false );                     }                 }             }         });     } } 
参考文章 ViewPager两种方式实现无限轮播 
ViewPager实现无限循环的2种方法