如何在ViewPager上进行循环滚动?

我想设置我的ViewPager做圆形滚动。 我希望第一页能够滚动到页面2和最后一页。 我想我的最后一页滚动到[最后一页-1]和第一页。 我做了一个尝试,虽然我不确定何时调用我创build的方法。 在ViewPager中似乎没有处理这种事情的方法,所以我创build了下面的代码。

public ViewPagerAdapter(final ViewPager pager, int... pageIDs) { super(); int actualNoOfIDs = pageIDs.length; count = actualNoOfIDs + 2; Log.d(TAG, "actualNoOfIDs: " + actualNoOfIDs + "count: " + count); pageIDsArray = new int[count]; for (int i = 0; i < actualNoOfIDs; i++) { pageIDsArray[ i + 1] = pageIDs[i]; } pageIDsArray[0] = pageIDs[actualNoOfIDs - 1]; pageIDsArray[count - 1] = pageIDs[0]; Log.d(TAG, "actualNoOfIDs#2: " + actualNoOfIDs + "count#2: " + count); pager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { int pageCount = getCount(); if (position == 0) { pager.setCurrentItem(pageCount - 2, false); } else if (position == pageCount - 1) { pager.setCurrentItem(1, false); } } @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub Log.d(TAG, "onPageScrollStateChanged()"); // if (state == ViewPager.SCROLL_STATE_IDLE) { // int pageCount = getCount(); // int currentItem = pager.getCurrentItem(); // if (currentItem == 0) { // pager.setCurrentItem(pageCount - 2, false); // } else if (currentItem == pageCount - 1) { // pager.setCurrentItem(1, false); // } // } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // TODO Auto-generated method stub Log.d(TAG, "onPageScrolled()"); } }); } 

我的整个代码有点冗长,但如果有帮助,我可以发布它。

 public class ViewPagerAdapter extends PagerAdapter { public static String TAG = ViewPagerAdapter.class.getSimpleName(); private int count; private int[] pageIDsArray; private TextToSpeech btnTTS; private TtsButton tTSBtn; String inputTxt; Context context; View itemView; TextView tvNumber; // container for atomic number TextView tvSymbol; // container for symbol TextView tvWeight; // container for weight TextView tvName; // container for name TextView tvGroup; // container for group TextView tvPeriod; // container for period TextView tvBlock; // container for block TextView tvFamily; // container for family TextView tvColor; // container for color TextView tvPhase; // container for phase TextView tvMelt; // container for melting point TextView tvBoil; // container for boiling point TextView tvNeutrons; // container for neutrons TextView tvProtons; // container for protons TextView tvElectrons; // container for electrons TextView tvUrl; // container for electrons public ViewPagerAdapter(Context context, List<Integer> arrayAtomicNum, List<String> arrayName, List<String> arraySymbol, List<String> arrayFamily, List<String> arrayPhase, List<String> arrayColor, List<Integer> arrayGroup, List<Integer> arrayPeriod, List<String> arrayBlock, List<Integer> arrayProtons, List<Integer> arrayNeutrons, List<Integer> arrayElectrons, List<Double> arrayWeight, List<Double> arrayMelt, List<Double> arrayBoil, List<String> arrayUrl) { this.context = context; ElementStructure.arrayAtomicNum = arrayAtomicNum; ElementStructure.arrayName = arrayName; ElementStructure.arraySymbol = arraySymbol; ElementStructure.arrayFamily = arrayFamily; ElementStructure.arrayPhase = arrayPhase; ElementStructure.arrayColor = arrayColor; ElementStructure.arrayGroup = arrayGroup; ElementStructure.arrayPeriod = arrayPeriod; ElementStructure.arrayBlock = arrayBlock; ElementStructure.arrayProtons = arrayProtons; ElementStructure.arrayNeutrons = arrayNeutrons; ElementStructure.arrayElectrons = arrayElectrons; ElementStructure.arrayWeight = arrayWeight; ElementStructure.arrayMelt = arrayMelt; ElementStructure.arrayBoil = arrayBoil; ElementStructure.arrayUrl = arrayUrl; } public ViewPagerAdapter(final ViewPager pager, int... pageIDs) { super(); int actualNoOfIDs = pageIDs.length; count = actualNoOfIDs + 2; Log.d(TAG, "actualNoOfIDs: " + actualNoOfIDs + "count: " + count); pageIDsArray = new int[count]; for (int i = 0; i < actualNoOfIDs; i++) { pageIDsArray[ i + 1] = pageIDs[i]; } pageIDsArray[0] = pageIDs[actualNoOfIDs - 1]; pageIDsArray[count - 1] = pageIDs[0]; Log.d(TAG, "actualNoOfIDs#2: " + actualNoOfIDs + "count#2: " + count); pager.setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { int pageCount = getCount(); if (position == 0) { pager.setCurrentItem(pageCount - 2, false); } else if (position == pageCount - 1) { pager.setCurrentItem(1, false); } } @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub Log.d(TAG, "onPageScrollStateChanged()"); // if (state == ViewPager.SCROLL_STATE_IDLE) { // int pageCount = getCount(); // int currentItem = pager.getCurrentItem(); // if (currentItem == 0) { // pager.setCurrentItem(pageCount - 2, false); // } else if (currentItem == pageCount - 1) { // pager.setCurrentItem(1, false); // } // } } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // TODO Auto-generated method stub Log.d(TAG, "onPageScrolled()"); } }); } @Override public int getCount() { // TODO Auto-generated method stub return ElementStructure.arrayAtomicNum.size(); } @Override public boolean isViewFromObject(View view, Object object) { // TODO Auto-generated method stub return view == ((RelativeLayout) object); } @Override public Object instantiateItem(ViewGroup container, final int position) { LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); int layoutColorId = ElementStructure.arrayLayoutColor.get(position); if (layoutColorId == 1) { itemView = inflater.inflate(R.layout.frame_learn_a, container, false); } else if (layoutColorId == 2) { itemView = inflater.inflate(R.layout.frame_learn_b, container, false); } else if (layoutColorId == 3) { itemView = inflater.inflate(R.layout.frame_learn_c, container, false); } else if (layoutColorId == 4) { itemView = inflater.inflate(R.layout.frame_learn_d, container, false); } Button btnSpeak = (Button)itemView.findViewById(R.id.btnaudio); btnSpeak.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub inputTxt = ElementStructure.arrayName.get(position); tTSBtn = new TtsButton(this, inputTxt); } }); // atomic number textView tvNumber = (TextView)itemView.findViewById(R.id.metanumber); // symbol textView tvSymbol = (TextView)itemView.findViewById(R.id.metasymbol); // weight textView tvWeight = (TextView)itemView.findViewById(R.id.metaweight); // name textView tvName = (TextView)itemView.findViewById(R.id.metaname); // group textView tvGroup = (TextView)itemView.findViewById(R.id.metagroup); // period textView tvPeriod = (TextView)itemView.findViewById(R.id.metaperiod); // block textView tvBlock = (TextView)itemView.findViewById(R.id.metablock); // family textView tvFamily = (TextView)itemView.findViewById(R.id.metafamily); // color textView tvColor = (TextView)itemView.findViewById(R.id.metacolor); // phase textView tvPhase = (TextView)itemView.findViewById(R.id.metaphase); // melting point textView tvMelt = (TextView)itemView.findViewById(R.id.metamelt); // boiling point textView tvBoil = (TextView)itemView.findViewById(R.id.metaboil); // neutrons textView tvNeutrons = (TextView)itemView.findViewById(R.id.metaneutrons); // protons textView tvProtons = (TextView)itemView.findViewById(R.id.metaprotons); // electrons textView tvElectrons = (TextView)itemView.findViewById(R.id.metaelectrons); // url textView tvUrl = (TextView)itemView.findViewById(R.id.metaurl); // capture position and set to the TextViews tvNumber.setText(String.valueOf(ElementStructure.arrayAtomicNum.get(position))); tvSymbol.setText(ElementStructure.arraySymbol.get(position)); tvWeight.setText(String.valueOf(ElementStructure.arrayWeight.get(position))); tvName.setText(ElementStructure.arrayName.get(position)); tvPeriod.setText(String.valueOf(ElementStructure.arrayPeriod.get(position))); tvBlock.setText(String.valueOf(ElementStructure.arrayBlock.get(position))); tvFamily.setText(ElementStructure.arrayFamily.get(position)); tvColor.setText(ElementStructure.arrayColor.get(position)); tvPhase.setText(ElementStructure.arrayPhase.get(position)); tvNeutrons.setText(String.valueOf(ElementStructure.arrayNeutrons.get(position))); tvProtons.setText(String.valueOf(ElementStructure.arrayProtons.get(position))); tvElectrons.setText(String.valueOf(ElementStructure.arrayElectrons.get(position))); tvUrl.setText(ElementStructure.arrayUrl.get(position)); // capture position, adjust for 0 value cases if (ElementStructure.arrayGroup.get(position) == 0) { tvGroup.setText("n/a"); } else { tvGroup.setText(String.valueOf(ElementStructure.arrayGroup.get(position))); } if (ElementStructure.arrayMelt.get(position) == 0) { tvMelt.setText("n/a"); } else { tvMelt.setText(String.valueOf(ElementStructure.arrayMelt.get(position))); } if (ElementStructure.arrayBoil.get(position) == 0) { tvBoil.setText("n/a"); } else { tvBoil.setText(String.valueOf(ElementStructure.arrayBoil.get(position))); } // add fragments to container (ViewPager) ((ViewPager) container).addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { Log.d(TAG, "destroyItem()"); // remove fragments from container (ViewPager) ((ViewPager) container).removeView((RelativeLayout) object); } @Override public void finishUpdate(View container) { // TODO Auto-generated method stub Log.d(TAG, "finishUpdate()"); } @Override public void restoreState(Parcelable state, ClassLoader loader) { // TODO Auto-generated method stub Log.d(TAG, "restoreState()"); } @Override public Parcelable saveState() { // TODO Auto-generated method stub Log.d(TAG, "saveState()"); return null; } @Override public void startUpdate(View container) { // TODO Auto-generated method stub Log.d(TAG, "startUpdate()"); } public class TtsButton extends Activity implements OnInitListener { public TtsButton(OnClickListener onClickListener, String inputTxt) { super(); tTSCheck(inputTxt); } private void tTSCheck (String inputTxt) { int resultCodeCheck = TextToSpeech.Engine.CHECK_VOICE_DATA_PASS; if (resultCodeCheck == 1) { btnTTS = new TextToSpeech(context, this); } else { Intent installTTSFiles = new Intent(); //missing data, install it installTTSFiles.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); startActivity(installTTSFiles); } } @Override public void onInit(int status) { // TODO Auto-generated method stub if(status == TextToSpeech.SUCCESS) { Log.i(TAG, "TTS INIT: SUCCESS"); btnTTS.setLanguage(Locale.US); btnTTS.speak(inputTxt, TextToSpeech.QUEUE_FLUSH, null); } else if(status == TextToSpeech.ERROR) { Log.e(TAG, "TTS INIT: ERROR"); } } @Override public void onPause() { if (btnTTS != null) { btnTTS.stop(); btnTTS.shutdown(); } super.onPause(); } } //end embedded class } //end ViewPagerAdapter 

提前致谢。 我正在考虑尝试使用动作手势,但是,我真的不明白为什么我的方法不能工作,所以我可以把它称为正确的位置。 我最初的想法是每当位置发生变化时,在“Object instantiateItem(ViewGroup container,final int position)”中调用它,并且条件是正确的。 但我不确定这是否是最好的。

这是一个没有伪造页面的解决scheme,像一个魅力:

 public class CircularViewPagerHandler implements ViewPager.OnPageChangeListener { private ViewPager mViewPager; private int mCurrentPosition; private int mScrollState; public CircularViewPagerHandler(final ViewPager viewPager) { mViewPager = viewPager; } @Override public void onPageSelected(final int position) { mCurrentPosition = position; } @Override public void onPageScrollStateChanged(final int state) { handleScrollState(state); mScrollState = state; } private void handleScrollState(final int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { setNextItemIfNeeded(); } } private void setNextItemIfNeeded() { if (!isScrollStateSettling()) { handleSetNextItem(); } } private boolean isScrollStateSettling() { return mScrollState == ViewPager.SCROLL_STATE_SETTLING; } private void handleSetNextItem() { final int lastPosition = mViewPager.getAdapter().getCount() - 1; if(mCurrentPosition == 0) { mViewPager.setCurrentItem(lastPosition, false); } else if(mCurrentPosition == lastPosition) { mViewPager.setCurrentItem(0, false); } } @Override public void onPageScrolled(final int position, final float positionOffset, final int positionOffsetPixels) { } } 

你只需要将它设置为你的ViewPager onPageChangeListener就是这样:

 viewPager.setOnPageChangeListener(new CircularViewPagerHandler(viewPager)); 

为了避免在你的ViewPager的“结尾”出现这个蓝色的光芒,你应该把这一行应用到放置ViewPager的xml中:

 android:overScrollMode="never" 

好的,我有一个答案。 这实际上比我想象的要容易些,但这确实需要一些技巧。 首先,让我从设置开始。 比方说,你有三个页面(ABC),你在ViewPager中滚动。 如果你继续在C上滚动(第3页),它会转到A(第1页),如果你在A(第1页)上向后滚动,它会转到C(第3页) )。

我不是说我的解决scheme是最好的,但它的工作原理,我没有看到任何问题。 首先,你必须创build两个“假”页面。 假页面代表ViewPager的第一页和最后一页。 接下来您将需要设置onPageChangeListener(),并使用onPageSelected()方法。 你需要伪造网页的原因是因为onPageSelected()只有在你移动(滑动)之后才会注册。 换句话说,如果没有这个方法,最终用户将不得不滚动到页面2并回到页面1来接收页面1上的命中,这也意味着页面1将被跳过,具体取决于您的代码逻辑。

设置是真正的完整答案。 一旦你有假的页面,这只是在必要的方法内使用setCurrentItem()的问题。

这是我的代码看起来如何。 一定要在你的容器中返回你的视图之前,把它放在你的公共对象instantiateItem(final ViewGroup容器,final int position)方法中。

 ((ViewPager) container).setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { Log.d(TAG, "onPageSelected() :: " + "position: " + position); // skip fake page (first), go to last page if (position == 0) { ((ViewPager) container).setCurrentItem(118, false); } // skip fake page (last), go to first page if (position == 119) { ((ViewPager) container).setCurrentItem(1, false); //notice how this jumps to position 1, and not position 0. Position 0 is the fake page! } } 

就是这样,它有诀窍! 唯一要做的就是在位置1上启动ViewPager(这是第二页:假页=第1页,我的真实起始页面=第2页)。 现在,每次滚动到假页面时,我都会将其redirect到最后一个真实页面。 每当我滚动到最后一个虚假的页面,我将它redirect到真正的起始页面(第2页)。

另外,不要尝试在onPageScrollStateChanged中放置任何代码。 那种方法是离奇的,看起来国家的价值是无法控制的。 它不断从一个国家跳到另一个国家。 即使没有滚动。 这只是我拿起的一个小费。

尝试这个

 ((ViewPager) container) .setOnPageChangeListener(new OnPageChangeListener() { @Override public void onPageSelected(int position) { Log.i("TAG", "pos::" + position); } @Override public void onPageScrollStateChanged(int state) { // TODO Auto-generated method stub int currentPage = pager.getCurrentItem(); Log.i("TAG", "currentPage::" + currentPage); Log.i("TAG", "currentState::" + currentState); Log.i("TAG", "previousState::" + previousState); if (currentPage == 4 || currentPage == 0) { previousState = currentState; currentState = state; if (previousState == 1 && currentState == 0) { pager.setCurrentItem(currentPage == 0 ? 4 : 0); } } } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO Auto-generated method stub } }); return 

这应该放在里面

  @Override public Object instantiateItem(final View container, int position) {} 

这是我的解决scheme:

myViewPager.java

 public class myViewPager extends PagerAdapter { public myViewPager (Context context) { this.context = context; } @Override public int getCount() { return rank.length+2; } @Override public boolean isViewFromObject(View view, Object object) { return view == object; } @Override public Object instantiateItem(ViewGroup container, int position) { // Declare Variables TextView textViewRank; //Log.i(TAG, "get position = "+position); inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); View itemView = inflater.inflate(R.layout.viewpager_item, container, false); textViewRank= (TextView) itemView.findViewById(R.id.textView1); if (position == getCount() - 1) { textViewRank.setText(rank[0]); } else if (position == 0) { textViewRank.setText(rank[rank.length-1]); } else { textViewRank.setText(rank[position-1]); } ((ViewPager) container).addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((View) object); } } 

viewpager_item.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" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/textView1"/> </LinearLayout> 

MainActivity.java

 public class MainActivity extends AppCompatActivity { private static final String TAG = MainActivity.class.getName(); public static String[] rank; myViewPager adapter; private ViewPager viewPager; private static int currentPage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); rank = new String[] { "1", "2", "3", "4", "5", "6", "7", "8", "9", "10" }; viewPager = (ViewPager) findViewById(R.id.view_pager); adapter = new myViewPager(this); viewPager.setAdapter(adapter); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageSelected(int position) { Log.i(TAG, "onPageSelected = "+position); currentPage = position; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // not needed } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { int pageCount = rank.length+2; if (currentPage == pageCount-1){ viewPager.setCurrentItem(1,false); } else if (currentPage == 0){ viewPager.setCurrentItem(pageCount-2,false); } } } }); } } 

activity_main.xml中

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v4.view.ViewPager android:id="@+id/view_pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="1" /> </LinearLayout> 

假设数组有10个元素。 然后“添加”2个虚拟元素,但不是真的添加。 当调用“get_count”函数时,只需返回size = 10 + 2个元素。

dummy e [0] e [1] e [2] e [3] e [4] e [5] e [6] e [8] e [9] dummy

在viewPager.addOnPageChangeListener中:

当你滑动到最后一个元素时,viewPager应该将第一个元素设置为next。

 if (currentPage == pageCount-1){ viewPager.setCurrentItem(1,false); } 

当你滑动到第一个元素时,viewPager应该把最后一个元素设置为next。

 else if (currentPage == 0){ viewPager.setCurrentItem(pageCount-2,false); } 

在instantiateItem中:

  if (position == getCount() - 1) { textViewRank.setText(rank[0]); } else if (position == 0) { textViewRank.setText(rank[rank.length-1]); } else { textViewRank.setText(rank[position-1]); } 

我试过@portfoliobuilder的解决scheme,这很好。 但是有一个小问题:当前项目是头部还是尾部,如果我只是点击ViewPager,而不是拖动,项目会变成尾部或头部。 我添加了一个触摸监听器来解决这个问题。

 skinPager.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //Record the x when press down and touch up, //to judge whether to scroll between head and tail int x = (int) event.getX(); int y = (int) event.getY(); if(event.getAction() == MotionEvent.ACTION_DOWN) skinPagerPressX = x; else if(event.getAction() == MotionEvent.ACTION_UP) skinPagerUpX = x; return false; } }); 

以下是portfoliobuilder的修改function:

 private void handleSetNextItem() { final int lastPosition = skinPager.getAdapter().getCount() - 1; //Only scroll when dragged if(mCurrentPosition == 0 && skinPagerUpX > skinPagerPressX) { skinPager.setCurrentItem(lastPosition, false); } else if(mCurrentPosition == lastPosition && skinPagerUpX < skinPagerPressX) { skinPager.setCurrentItem(0, false); } } 

@tobi_b的答案并不完全成功,因为从最后到最后(至less在我的试验中)没有顺利的滑动。 但我真的很受他的回答启发。 我的解决scheme是,当从最后一个虚拟跳到真实的时候,等到上一次滚动完成。 这是我的代码,非常简单,

 private final class MyPageChangeListener implements OnPageChangeListener { private int currentPosition; @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE) { if (currentPosition == viewPager.getAdapter().getCount() - 1) { viewPager.setCurrentItem(1, false); } else if (currentPosition == 0) { viewPager.setCurrentItem(viewPager.getAdapter().getCount() - 2, false); } } } @Override public void onPageScrolled(int scrolledPosition, float percent, int pixels) { //empty } @Override public void onPageSelected(int position) { currentPosition = position; } } 

但是,这个解决scheme并不完美。 当从最后一个滑到第一个时,它有一点缺陷。 如果我们在很短的时间内滑动两次,第二张幻灯片将失效。 这个问题需要解决。

我创build了圆滑的viewpager,从左到右滑动滚动,从右到左滑动,第一个滑动到最后。

为此添加最后一页在开始和第一页到最后: addOnPageChangeListener里面:我们必须做一些计算,当我们是0的位置,然后onPageScrollStateChanged设置当前项目作为最后一个项目,反之亦然。

看看代码

 public class ViewPagerCircular_new extends AppCompatActivity { ViewPager viewPager; ArrayList<String> str = new ArrayList<String>(); boolean chageImage = false; int setPos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.view_pager_normal); viewPager = (ViewPager) findViewById(R.id.vf_home_top_pager); str.add("6"); // added the last page to the frist str.add("1"); // First item to display in view pager str.add("2"); str.add("3"); str.add("4"); str.add("5"); str.add("6"); // last item to display in view pager str.add("1"); // added the first page to the last ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager()); viewPager.setAdapter(adapter); viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { if (position == str.size() - 1) { chageImage = true; setPos = 1; } else if (position == 0) { chageImage = true; setPos = str.size() - 2; } else { chageImage = false; } } @Override public void onPageSelected(int position) { } @Override public void onPageScrollStateChanged(int state) { if (state == ViewPager.SCROLL_STATE_IDLE && chageImage) { viewPager.setCurrentItem(setPos, false); } } }); // display the 1st item as current item viewPager.setCurrentItem(1); } 

//页面适配器

 public class ViewPagerAdapter extends FragmentStatePagerAdapter { public ViewPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { PagerFragment fragment = new PagerFragment(); Bundle bundle = new Bundle(); bundle.putString("pos", str.get(position)); fragment.setArguments(bundle); return fragment; } @Override public int getCount() { return str.size(); } } 

//片段显示在适配器中

 public class PagerFragment extends Fragment { Bundle bundle; String pos; public PagerFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bundle = getArguments(); pos = bundle.getString("pos"); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(ViewPagerCircular_new.this); textView.setGravity(Gravity.CENTER); textView.setTextSize(25); textView.setText(pos); return textView; } } 

}

我稍微修改了@portfoliobuilder的答案。 这很简单。 设置当前的项目没有平滑滚动,直到PageChangeState为“0”,所以它会非常stream畅。

 ((ViewPager)container).setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { currentPage = position; } @Override public void onPageScrollStateChanged(int state) { // state equals to 0 means the scroll action is stop if(state == 0) { if(currentPage == 0) ((ViewPager)container).setCurrentItem(imageResourceList.size()-2,false); if(currentPage == imageResourceList.size()-1) ((ViewPager)container).setCurrentItem(1,false); } } }); 

解决了从第一页滑动到最后一页从右到左移动时animation的缺失,反之亦然

@tobi_b答案稍作修改,解决了我的问题。 为此,将起始页和最后一页的副本添加到最后一页。然后从PagerAdapter中的下面的方法中删除NOT运算符,并将setCurrentItem(lastposition,false)更改为setCurrentItem(lastposition-1,false) setCurrentItem(0,false)到setCurrentItem(1,false)。

 private void setNextItemIfNeeded() { if (isScrollStateSettling()) { handleSetNextItem(); } } private boolean isScrollStateSettling() { return mScrollState == ViewPager.SCROLL_STATE_SETTLING; } private void handleSetNextItem() { final int lastPosition = pager.getAdapter().getCount() - 1; if(mCurrentPosition == 0) { pager.setCurrentItem(lastPosition-1, false); } else if(mCurrentPosition == lastPosition) { pager.setCurrentItem(1, false); } } 

并在您的MainActivity.java不要忘记将当前项目设置为1.希望这将有助于一些。