2

I am facing an issue with the ViewPager to make it cyclic. I have a list of data which is dynamic and everytime a swipe is made the view has to be updated with dynamic data. For example, I have some 5 objects in list say A,B,C,D,E I am able to swipe through from A -> B -> C -> D -> E and again from E -> D -> C -> B -> A. But I should make it cyclic as in after E, it should goto A on swiping right and after A it should goto E on swiping left. Please can some one tell me how to do this. Thanks a lot.

Here is my code snippet which I have tried so far.

public class FlingActivity extends BaseActivity implements OnClickListener{

private ViewPager pager;
private int position;
private int total;
private ArrayList<DataBean> beanList;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);     
    setContentView(R.layout.main);

    if (this.getIntent().hasExtra("position")) {
        position = (int) this.getIntent().getExtras().getInt("position");
    }
    if(getIntent().hasExtra("listDetails")) {
        beanList = (ArrayList<DataBean>)getIntent().getSerializableExtra("listDetails");
    }

    if(beanList != null){
        total = beanList.size();
        pager = (ViewPager) findViewById(R.id.pager);
        ((RelativeLayout) findViewById(R.id.right_arrow)).setOnClickListener(this);
        ((RelativeLayout) findViewById(R.id.left_arrow)).setOnClickListener(this);  
        pager.setVisibility(View.VISIBLE);

        pager.setAdapter(new MyPagerAdapter(beanList));
        pager.setOnPageChangeListener(new OnPageChangeListener() {
            int lastPosition;
            int posOffset=0;
            public void onPageSelected(int arg0) {
                position=arg0;
            }

            public void onPageScrolled(int arg0, float arg1, int arg2) {
                if(arg0!=0 && arg1==0 && arg2 == 0){
                    lastPosition=arg0;
                }
            }

            public void onPageScrollStateChanged(int arg0) {
                if(position == total - 1){
                    position=total + 1;
                }
                if(arg0 == ViewPager.SCROLL_STATE_IDLE && position > total){
                    pager.setCurrentItem(0, true);
                }
            }
        });
        pager.setCurrentItem(position, true);

    }

}   

public void onClick(View v) {
    switch(v.getId()) {
    case R.id.left_arrow:
        if(pager != null) {
            pager.setCurrentItem(pager.getCurrentItem() - 1, true);
        }

        break;
    case R.id.right_arrow:
        if(pager != null) {             
            pager.setCurrentItem(pager.getCurrentItem() + 1, true);
        }

        break;
    }       
}

private class MyPagerAdapter extends PagerAdapter {
    private ArrayList<DataBean> beanList;
    public MyPagerAdapter(ArrayList<DataBean> list) {
        this.beanList = list;
    }

    public int getCount() {
        return beanList.size();
    }

    public Object instantiateItem(View collection, int position) {
        View view = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item_view, null);

        DataBean dataBean = beanList.get(position); 
        TextView name = (TextView) view.findViewById(R.id.name);
        name.setText(dataBean.getName());

        TextView description = (TextView) view.findViewById(R.id.desc);
        description.setText("Description " 
                                + dataBean.getDesc());

        ((ViewPager) collection).addView(view, 0);
        return view;            
    }

    @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);
    }       
}

}

In the above code after going to E the page automatically slides to A but it should actually go to A only if the user swipes.

Lavanya
  • 3,903
  • 6
  • 31
  • 57

1 Answers1

0

We can return a multiple number of our actual fragment list size in adapter getCount to loop through the fragment list multiple times. We can then return the sequential fragment instances by checking the index position modulated by the total number of fragments.

More on this here -> https://medium.com/@ali.muzaffar/looping-infinite-viewpager-with-page-indicator-in-android-ce741f25702a

final FragmentStateAdapter collectionAdapter = new FragmentStateAdapter(this) {
            @NonNull
            @Override
            public Fragment createFragment(int position) {
                final Fragment fragment;
                int index = position % TOTAL_NUMBER_OF_FRAGMENTS;   // 6 in my case
                switch (index) {
                    case 0:
                        fragment = new StreamFragment()
                        break;
                    ....
                    default:
                        fragment = new DemoFragment();
                        break;
                }
                return fragment;
            }

            @Override
            public int getItemCount() {
                return MAX_NUMBER_OF_LOOPING;   // set to 60, return a multiple of your actual fragment list
            }
        };

For page indicator I used a tab layout and there I did the same:

new TabLayoutMediator(binding.tabLayout, binding.viewPager, (tab, position) -> {
            final String tabText;
            int index = position % TOTAL_NUMBER_OF_FRAGMENTS;
            switch (index) {
                case 0:
                    tabText = NAVIGATION_MODE;
                    break;
                case 1:
                    tabText = FOCUS_MODE;
                    break;
                ....
            } tab.setText(tabText);
        }).attach();
Ronnie
  • 207
  • 4
  • 11