Je souhaite configurer mon ViewPager pour le défilement circulaire. Je veux que la première page puisse faire défiler jusqu'à la page 2 ET la dernière page. Et je voudrais que ma dernière page défile jusqu'à [dernière page -1] ET la première page. J'ai essayé, mais je ne sais pas quand appeler la méthode que j'ai créée. Il ne semble pas y avoir de méthode dans ViewPager qui gère ce genre de chose, alors j'ai créé le ci-dessous.
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()");
}
});
}
Mon code entier est un peu long, mais si cela peut aider, je peux le poster.
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
Merci d'avance. Je pensais essayer d'utiliser le geste de la motion, cependant, je ne comprends vraiment pas pourquoi ma méthode ne fonctionnera pas si longtemps que je peux l'appeler au bon endroit. Mon idée initiale était de l'appeler "Objet instantiateItem (conteneur ViewGroup, position finale finale)" chaque fois que la position change et si les conditions étaient correctes. Mais je ne suis pas sûr que ce soit le mieux.
Ok, j'ai une réponse. C'était en fait plus facile que prévu, mais cela demande un peu de ruse. Tout d’abord, laissez-moi commencer par la mise en place. Disons, par exemple, que vous faites défiler trois pages (A-B-C) dans votre ViewPager. Et vous voulez le configurer de sorte que si vous continuez à faire défiler sur C (p. 3), il passe à A (p. 1) et si vous faites défiler en arrière sur A (p. 1), il passe à C (p. 3). ).
Je ne dis pas que ma solution est la meilleure, mais cela fonctionne et je ne vois aucun problème. Tout d'abord, vous devez créer deux "fausses" pages. Les fausses pages représentent les première et dernière pages de votre ViewPager. La prochaine chose dont vous aurez besoin est de configurer onPageChangeListener () et d’utiliser la méthode onPageSelected (). La raison pour laquelle vous avez besoin des fausses pages est parce que onPageSelected () ne s'enregistre qu'après avoir déplacé (balayé). En d’autres termes, sans cette méthode, l’utilisateur final devrait passer à la page 2 et revenir à la page 1 pour recevoir un hit à la page 1, ce qui signifie également que la page 1 serait ignorée en fonction de la logique de votre code.
La configuration est vraiment la réponse entière. Une fois que vous avez vos fausses pages, il suffit d’utiliser setCurrentItem () dans la méthode nécessaire.
Voici à quoi ressemble mon code. Assurez-vous de placer cette information dans votre méthode publique objet instantiateItem (conteneur ViewGroup final, position finale) avant de retourner votre vue à l'intérieur de votre conteneur.
((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!
}
}
Ça y est, ça fait l'affaire! La seule autre chose à faire est de démarrer votre ViewPager à la position 1 (qui est la deuxième page: fake page = pg 1, ma vraie page de départ = pg 2). Maintenant, chaque fois que je défile vers la fausse page, je la redirige vers la dernière page réelle. Et chaque fois que je défile vers l’avant vers la dernière fausse page, je la redirige vers la page de départ réelle (p. 2).
Aussi, n'essayez pas de mettre du code dans onPageScrollStateChanged. Cette méthode est bizarre, il semble que la valeur de l’état soit incontrôlable. Il saute constamment d'un état à un autre. Même sans défilement. C'est juste un pourboire que j'ai ramassé.
Ceci est une solution sans fausse page et fonctionne comme un charme:
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) {
}
}
Vous devez simplement le définir sur votre ViewPager en tant que onPageChangeListener et le tour est joué:
viewPager.setOnPageChangeListener(new CircularViewPagerHandler(viewPager));
Pour éviter que ce bleu ne brille à la "fin" de votre ViewPager, vous devez appliquer cette ligne à votre xml où le ViewPager est placé:
Android:overScrollMode="never"
J'ai créé le viewpager circulaire avec un défilement régulier du dernier au premier glissement à gauche et du premier au dernier glissement à droite.
Pour cela, ajoutez la dernière page au début et la première page à la dernière: Dans addOnPageChangeListener: nous devons effectuer un calcul, lorsque nous sommes à 0 position, puis sur onPageScrollStateChanged, définit l'élément actuel comme dernier élément et vice-versa.
Regarde le code
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);
}
// adaptateur de téléavertisseur
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();
}
}
// fragment à afficher dans l'adaptateur
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;
}
}
}
J'ai légèrement modifié la réponse de @portfoliobuilder. C’est très simple . Régler l’élément en cours sans défilement régulier jusqu’à ce que PageChangeState
soit égal à "0", de sorte que ce serait très lisse.
((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);
}
}
});
Essaye ça
((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
Cela devrait être placé à l'intérieur
@Override
public Object instantiateItem(final View container, int position) {}
Ceci est ma solution:
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>
Supposons que le tableau a 10 éléments. Puis "ajouter" 2 éléments factices, mais pas vraiment ajouter. Lorsque la fonction "get_count" est appelée, il suffit de retourner size = 10 + 2 elements.
dummy e [0] e [1] e [2] e [3] e [4] e [5] e [6] e [7] e [8] e [9] dummy
Dans viewPager.addOnPageChangeListener:
lorsque vous passez au dernier élément, viewPager doit définir le premier comme le suivant.
if (currentPage == pageCount-1){
viewPager.setCurrentItem(1,false);
}
lorsque vous passez au premier élément, viewPager doit définir le dernier élément comme suivant.
else if (currentPage == 0){
viewPager.setCurrentItem(pageCount-2,false);
}
Dans 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]);
}
J'ai essayé la solution de @ portfoliobuilder, c'est génial. Mais il y a un petit problème: lorsque l'élément actuel est la tête ou la queue, si je ne fais que cliquer sur le ViewPager, sans le faire glisser, l'élément se changera en queue ou en tête. Et j'ai ajouté un écouteur tactile au ViewPager pour résoudre le problème.
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;
}
});
Voici la fonction modifiée de portfoliobuilder:
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);
}
}
La réponse de @tobi_b n'est pas totalement réussie, car elle ne glisse pas facilement du dernier au premier (du moins dans mon essai). Mais sa réponse m'a vraiment inspiré… .. Ma solution est qu'il est temps de passer du faux au dernier faux, d'attendre que le dernier défilement soit terminé. Voici mon code, c'est très simple,
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;
}
}
Cependant, cette solution n'est pas parfaite. Il y a un petit défaut quand on glisse vite du dernier au premier. Si nous glissons deux fois en très peu de temps, la deuxième diapositive sera invalidée. Ce problème doit être résolu.
Résolution du manque d'animation en allant de droite à gauche en glissant la première page à la dernière et inversement
Une légère modification dans la réponse @tobi_b a résolu mon problème . Pour cette copie ajoutée de la dernière page au début et de la première page à la dernière.Ensuite, supprimez l'opérateur NOT de la méthode ci-dessous dans PagerAdapter.And change setCurrentItem (lastposition, false) à setCurrentItem (lastposition-1, false) et 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);
}
}
Et dans votre MainActivity.Java, n'oubliez pas de définir l'élément en cours sur 1 . En espérant que cela vous aidera.