Comme indiqué par Google, la classe Gallery était obsolète dans l'API de niveau 16. Ce widget n'est plus pris en charge. HorizontalScrollView et ViewPager de la bibliothèque de support sont d'autres widgets à défilement horizontal. J'ai donc utilisé ViewPager comme alternative à la classe Gallery.
Mon objectif est d’atteindre un défilement infini de l’image ViewPager avec description de texte . J'ai utilisé le code ci-dessous pour obtenir l'image ViewPager avec un texte décrivant chaque image, mais comment appliquer le défilement infini à un ViewPager?
Je n'ai pas travaillé avec ViewPager auparavant, alors essayez de fournir un code détaillé si possible.
activity_main.xml:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical">
<Android.support.v4.view.ViewPager
Android:id="@+id/myimagepager"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
</LinearLayout>
custom_pager.xml:
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical"
Android:gravity="center_horizontal">
<ImageView
Android:id="@+id/myimage"
Android:layout_width="match_parent"
Android:layout_height="0dp"
Android:layout_margin="5dp"
Android:layout_weight="2" />
<TextView
Android:id="@+id/image_text"
Android:layout_width="fill_parent"
Android:layout_height="0dp"
Android:layout_weight="1"/>
</LinearLayout>
ImagePager:
public class ImagePager extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra, stringArray );
ViewPager myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(0);
}
private int imageArra[] = { R.drawable.a, R.drawable.b,R.drawable.c,
R.drawable.d,R.drawable.e,R.drawable.f,
R.drawable.g, R.drawable.h, R.drawable.i};
private String[] stringArray = new String[] { "Image a", "Image b","Image c"
"Image d","Image e","Image f",
"Image g","Image h","Image i"};
}
ImagePagerAdapter:
public class ImagePagerAdapter extends PagerAdapter {
Activity activity;
int imageArray[];
String[] stringArray;
public ImagePagerAdapter(Activity act, int[] imgArra, String[] stringArra) {
imageArray = imgArra;
activity = act;
stringArray = stringArra;
}
public int getCount() {
return imageArray.length;
}
public Object instantiateItem(View collection, int position) {
LayoutInflater inflater = (LayoutInflater)collection.getContext
().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_pager, null);
ImageView im=(ImageView) layout.findViewById(R.id.myimage);
im.setImageResource(imageArray[position]);
TextView txt=(TextView) layout.findViewById(R.id.image_text);
txt.setText(stringArray[position]);
((ViewPager) collection).addView(layout, 0);
return layout;
}
@Override
public void destroyItem(View arg0, int arg1, Object arg2) {
((ViewPager) arg0).removeView((View) arg2);
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == ((View) arg1);
}
@Override
public Parcelable saveState() {
return null;
}
}
J'ai eu le même problème , mais j'ai pu trouver un moyen de le résoudre - le code se trouve sur github .
Si vous copiez les classes InfiniteViewPager et InfinitePagerAdapter dans votre projet, vous pouvez réaliser un défilement infini (enveloppé) avec de petites modifications.
Dans votre activité, enveloppez votre PagerAdapter avec une InfinitePagerAdapter
:
PagerAdapter adapter = new InfinitePagerAdapter(new ImagePagerAdapter(this, imageArra, stringArray));
Changez le ViewPager dans le code XML d'activité en InfiniteViewPager
:
<com.antonyt.infiniteviewpager.InfiniteViewPager
Android:id="@+id/myimagepager"
Android:layout_width="match_parent"
Android:layout_height="match_parent" />
Vous pouvez renommer les classes comme vous le souhaitez. Ce code ne fonctionne que si vous avez au moins trois pages (vous en avez neuf dans votre exemple de code, donc cela fonctionnera bien pour cela).
j'ai déjà trouvé un moyen en faisant simple tour, j'espère que cela vous aide
import Java.util.ArrayList;
import Android.os.Bundle;
import Android.app.Activity;
import Android.support.v4.view.ViewPager;
import Android.support.v4.view.ViewPager.OnPageChangeListener;
import Android.util.Log;
public class ImagePager extends Activity {
String[] stringArray;
int[] imageArra;
ViewPager myPager;
Boolean isScrooled = false;
// use this array yo understand swipe left or right ?
ArrayList<Float> pos = new ArrayList<Float>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// put empty view at the beginnig and to end
imageArra = new int[] { 0, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher, 0 };
// put empty string at the beginnig and to end
stringArray = new String[] { "", "Image a", "Image b", "Image c",
"Image d", "Image e", "Image f", "Image g", "Image h",
"Image i", "" };
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra,
stringArray);
myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(1);
myPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.v("onPageSelected", String.valueOf(arg0));
pos.clear();
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
try {
// while scrolling i add ever pos to array
pos.add(arg1);
// if pos.get(0) > pos.get(pos.size() - 1)
// <----- swipe <-----
// we should check isScroll because setCurrent item is not a croll ?
if (pos.size() > 0)
if (arg0 == imageArra.length - 1
& pos.get(0) > pos.get(pos.size() - 1)
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(1, false);
} catch (Exception e) {
Log.v("hata",
"<----- swipe <----- " + e.toString());
}
}
// ----> swipe ---->
else if (arg0 == 0
& pos.get(0) < pos.get(pos.size() - 1)
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(imageArra.length - 1,
false);
} catch (Exception e) {
Log.v("hata",
"----> swipe ----> " + e.toString());
}
} else if (arg0 == 0 & pos.size() == 1
& isScrooled == true) {
try {
isScrooled = false;
myPager.setCurrentItem(imageArra.length - 1,
false);
} catch (Exception e) {
Log.v("hata",
"----> swipe ----> " + e.toString());
}
}
} catch (Exception e) {
Log.v("hata", e.toString());
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.v("onPageScrollStateChanged", String.valueOf(arg0));
// set is scrolling
isScrooled = true;
}
});
}
}
[EDIT 1]
import Java.util.ArrayList;
import Android.app.Activity;
import Android.os.Bundle;
import Android.support.v4.view.ViewPager;
import Android.support.v4.view.ViewPager.OnPageChangeListener;
import Android.util.Log;
public class ImagePager extends Activity {
String[] stringArray;
int[] imageArra;
ViewPager myPager;
int scrollState;
Boolean isFirstVisitEnd= true,isFirstVisitBegin = true;
ArrayList<Integer> pos = new ArrayList<Integer>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageArra = new int[] { 0,R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher,
R.drawable.ic_launcher, R.drawable.ic_launcher, 0 };
stringArray = new String[] {"","Image a", "Image b", "Image c",
"Image d", "Image e", "Image f", "Image g", "Image h",
"Image i", "" };
ImagePagerAdapter adapter = new ImagePagerAdapter(this, imageArra,
stringArray);
myPager = (ViewPager) findViewById(R.id.myimagepager);
myPager.setAdapter(adapter);
myPager.setCurrentItem(1);
myPager.setOnPageChangeListener(new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Log.v("onPageSelected", String.valueOf(arg0));
pos.clear();
if (arg0 == imageArra.length - 1)
isFirstVisitEnd = false;
else
isFirstVisitEnd = true;
if (arg0 == 0)
isFirstVisitBegin = false;
else
isFirstVisitBegin = true;
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
try {
pos.add(Integer.valueOf(arg2));
if (pos.size() > 0) {
//Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitEnd: "+String.valueOf(isFirstVisitEnd.booleanValue()) );
// <----- swipe <-----
if (arg0 == imageArra.length - 2& (pos.get(pos.size() - 1) -pos.get(0) < 100)& scrollState == 2 & isFirstVisitEnd == false) {
myPager.setCurrentItem(1, false);
}
//Log.v("onPageScrolled_arg2","arg0 : "+String.valueOf(arg0)+" ilk : "+pos.get(0).toString()+" son : " +pos.get(pos.size() - 1).toString()+ " "+ String.valueOf(pos.get(0)-(pos.get(pos.size() - 1)))+" isFirstVisitbegin: "+String.valueOf(isFirstVisitBegin.booleanValue()) );
if (arg0 == 0 & (pos.get(pos.size() - 1) -pos.get(0) > -100)& scrollState == 2 & isFirstVisitBegin == false) {
myPager.setCurrentItem(imageArra.length - 2, false);
}
}
} catch (Exception e) {
Log.v("hata", e.toString());
}
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.v("onPageScrollStateChanged", String.valueOf(arg0));
scrollState =arg0;
}
});
}
}
Je pense que ma solution est plus simple.
Attention à mon tableau de structure d'images:
Item 0 => last image
Item count()-1 => first image
Le truc est sur onPageScrollStateChanged
:
Lorsque l'utilisateur fait défiler jusqu'au dernier élément -> le téléavertisseur passe sans animation à la première image (position = 1)
Lorsque l'utilisateur fait défiler jusqu'au premier élément -> le téléavertisseur passe sans animation à la dernière image (position = nombre - 2)
public class InfiniteScrollingActivity extends ActionBarActivity {
private ViewPager pager;
private MyAdapter adapter;
int[] promoImageIds = new int[]{R.drawable.cover6, R.drawable.cover1, R.drawable.cover2, R.drawable.cover3, R.drawable.cover4, R.drawable.cover5, R.drawable.cover6, R.drawable.cover1 };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_test);
adapter = new MyAdapter(getSupportFragmentManager(), promoImageIds);
pager = (ViewPager)findViewById(R.id.pager);
pager.setAdapter(adapter);
pager.setCurrentItem( 1 );
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int index) {
Log.v( "onPageSelected", String.valueOf( index ) );
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// Log.v("onPageScrolled", "");
}
@Override
public void onPageScrollStateChanged(int state) {
Log.v("onPageScrollStateChanged", String.valueOf(state));
if (state ==ViewPager.SCROLL_STATE_IDLE) {
int index = pager.getCurrentItem();
if ( index == 0 )
pager.setCurrentItem( adapter.getCount() - 2, false );
else if ( index == adapter.getCount() - 1 )
pager.setCurrentItem( 1 , false);
}
}
});
}
public static class MyAdapter extends FragmentPagerAdapter {
int[] promoImageIds;
public MyAdapter(FragmentManager fm, int[] promoImageIds){
super(fm);
this.promoImageIds = promoImageIds;
}
@Override
public int getCount(){
return promoImageIds.length;
}
@Override
public Fragment getItem(int position) {
return PromoFragment.newInstance( promoImageIds[position] );
}
}
public static class PromoFragment extends Fragment
{
int imageID;
static PromoFragment newInstance( int imageID)
{
PromoFragment f = new PromoFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putInt( "imageID", imageID );
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
imageID = getArguments() != null ? getArguments().getInt( "imageID" ) : null;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
ImageView v = (ImageView) inflater.inflate(R.layout.fragment_image, container, false);
v.setImageResource( imageID );
return v;
}
}
}
J'ai trouvé une autre solution, basée sur Shlomi Hasin et antonyt answers, sans modifier la collection.
ViewPager yourPager;
PagerAdapter yourAdapter;
//....
EndlessPagerAdapter endlessPagerAdapter = new EndlessPagerAdapter(yourAdapter, yourPager);
yourPager.setAdapter(endlessPagerAdapter);
yourPager.setCurrentItem(1);//for correct first page
Classe complète:
public class EndlessPagerAdapter extends PagerAdapter {
private PagerAdapter adapter;
public EndlessPagerAdapter(PagerAdapter adapter, ViewPager viewPager) {
this.adapter = adapter;
viewPager.addOnPageChangeListener(new SwapPageListener(viewPager));
}
@Override
public int getCount() {
return adapter.getCount() + 2;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
if (adapter.getCount() < 2) {
adapter.instantiateItem(container, position);
}
int newPosition;
if (position == 0) {
newPosition = adapter.getCount() - 1;
} else if (position >= getCount() - 1) {
newPosition = 0;
} else {
newPosition = position - 1;
}
return adapter.instantiateItem(container, newPosition);
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
adapter.destroyItem(container, position, object);
}
@Override
public void finishUpdate(ViewGroup container) {
adapter.finishUpdate(container);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return adapter.isViewFromObject(view, object);
}
@Override
public void restoreState(Parcelable bundle, ClassLoader classLoader) {
adapter.restoreState(bundle, classLoader);
}
@Override
public Parcelable saveState() {
return adapter.saveState();
}
@Override
public void startUpdate(ViewGroup container) {
adapter.startUpdate(container);
}
@Override
public CharSequence getPageTitle(int position) {
return adapter.getPageTitle(position);
}
@Override
public float getPageWidth(int position) {
return adapter.getPageWidth(position);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
adapter.setPrimaryItem(container, position, object);
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
adapter.unregisterDataSetObserver(observer);
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
adapter.registerDataSetObserver(observer);
}
@Override
public void notifyDataSetChanged() {
adapter.notifyDataSetChanged();
}
@Override
public int getItemPosition(Object object) {
return adapter.getItemPosition(object);
}
private class SwapPageListener implements ViewPager.OnPageChangeListener {
private ViewPager viewPager;
SwapPageListener(ViewPager viewPager) {
this.viewPager = viewPager;
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
}
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
PagerAdapter pagerAdapter = viewPager.getAdapter();
if (pagerAdapter != null) {
int itemCount = pagerAdapter.getCount();
if (itemCount < 2) {
return;
}
int index = viewPager.getCurrentItem();
if (index == 0 ) {
viewPager.setCurrentItem(itemCount - 2, false);
} else if (index == itemCount - 1) {
viewPager.setCurrentItem(1, false);
}
}
}
}
}}
Comment ça marche:
Nous avons une collection
puis ajoutez-lui deux objets supplémentaires
affiche le premier élément sur la dernière position et le dernier élément sur la première position
ajouter un auditeur et échanger des pages sur un événement, de 4 à 1 et de 0 à 3
c'est tout.
Je ne vous conseillerais pas d'appliquer l'animation ici ou les mises en page lourdes, cela peut être en retard lorsque des éléments sont échangés (peut-être que je n'ai pas rencontré de retard).
Ne définissez pas non plus cet adaptateur sur un pageur plus d'une fois, ni ne déplacez SwapPageListener vers une classe externe et définissez-le dans un bloc d'initialisation.
RecyclerViewPager a implémenté infinite scrolling
et peut défiler comme une galerie.
Pour le défilement infini avec les jours, il est important que vous ayez le bon fragment dans le pager, c’est pourquoi j’ai écrit ma réponse sur cette page ( Viewpager dans Android pour basculer d’un jour à l’autre )
Cela fonctionne très bien! Les réponses ci-dessus n'ont pas fonctionné pour moi car je voulais que cela fonctionne.
if ((pagerBottom.getCurrentItem() + 1) == (sliderimageDetails.size())) {
pagerBottom.setCurrentItem(0);
} else {
pagerBottom.setCurrentItem((pagerBottom.getCurrentItem() + 1));
}