Viewpager in Android to switch between days endlessly

10.4k views Asked by At

I am currently making a app where students can view there lesson grid. The lessons are retrieved using a json file. Now the date changing is done via buttons in the actionbar, but i want to make it also work with smooth swipe effects.

The only things that need to change is the SlectedDate-1 on left swipe. the SelectedDate+1 on right swipe.

I tried it with ViewPagers but it didn't work does anybody know how to do it? Maybe something with 3 viewpagers?, please a detailed code because I'm not very familar with viewpagers code!

I've tried out Android ViewPager working with date code but it doesn't work for me.

 private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        String myFormat = "yyyy-MM-dd"; 
        SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);

         switch (position) {
           case 0:
                  // create your dates for the leftmost fragment  
                    myCalendar.add(Calendar.DAY_OF_YEAR, -1);
                    final String dateje = sdf.format(myCalendar.getTime());
                   // mPager.setCurrentItem(1);
                  return ScreenSlidePageFragment.create(dateje);


              case 1:
                  // create your dates for the center fragment 
                  myCalendar.add(Calendar.DAY_OF_YEAR, 0);
                final String dateje2 = sdf.format(myCalendar.getTime());
              //mPager.setCurrentItem(1);
              return ScreenSlidePageFragment.create(dateje2);

              case 2: 
                  myCalendar.add(Calendar.DAY_OF_YEAR, 1);
                final String dateje3 = sdf.format(myCalendar.getTime());
              //mPager.setCurrentItem(1);

              return ScreenSlidePageFragment.create(dateje3);
           }

      return null;
    }

    @Override
    public int getCount() {
        return 3;
    }

my example fragment

public class ScreenSlidePageFragment extends Fragment {
    /**
     * The argument key for the page number this fragment represents.
     */
    public static final String ARG_PAGE = "page";

    /**
     * The fragment's page number, which is set to the argument value for {@link #ARG_PAGE}.
     */
    private int mPageNumber;

    /**
     * Factory method for this fragment class. Constructs a new fragment for the given page number.
     */
    public static ScreenSlidePageFragment create(String dateNumber) {
        ScreenSlidePageFragment fragment = new ScreenSlidePageFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PAGE, dateNumber);
        fragment.setArguments(args);
        return fragment;
    }

    public ScreenSlidePageFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPageNumber = 1;



    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout containing a title and body text.
        ViewGroup rootView = (ViewGroup) inflater
                .inflate(R.layout.fragment_screen_slide_page, container, false);


        String date = this.getArguments().getString(ARG_PAGE);
        // Set the title view to show the page number.
        ((TextView) rootView.findViewById(android.R.id.text1)).setText(date);

        return rootView;
    }

    /**
     * Returns the page number represented by this fragment object.
     */
    public int getPageNumber() {
        return mPageNumber;
    }
}
2

There are 2 answers

2
Richard Lindhout On BEST ANSWER

I have fixed this problems a little time ago, this code is a bit based on the answer from Kuffs but I don't get the date in an array because it's a lot of performance to put a lot of days in array.

Summary of code (1) The code makes a FragmentPager with around 10.000 pages in it. On the main activity init the app set the current page to the middle(5000).

pager.setAdapter(new BootstrapPagerAdapter(getResources(), getSupportFragmentManager()));
pager.setCurrentItem(5000, false);
pager.post(new Runnable() {
    public void run() {
        pager.setCurrentItem(5000, false);
    }
});
pager.getAdapter().notifyDataSetChanged();
pager.setOffscreenPageLimit(0);

Summary of code (2) in the bootstrappageradapter

The code looks what position the user has scrolled and looks for the date now

DateTime pagerdate = DateTime.now(TimeZone.getDefault());
DateTime days = pagerdate.plusDays(position - 5000);

e.g. user swiped three days next. position is 5003, so the sum is 5003-5000=3 days

The days count easily plus 3 days with date4j library (I highly recommend it!) then I make a new fragment with the date in its bundle!

public class BootstrapPagerAdapter extends FragmentPagerAdapter
{
    /**
    * Create pager adapter
    *
    * @param resources
    * @param fragmentManager
    */
    public BootstrapPagerAdapter(Resources resources, FragmentManager fragmentManager) {
        super(fragmentManager);
    }

    @Override
    public int getCount() {
        return 10000;
    }

    @Override
    public int getItemPosition(Object object){
        return FragmentStatePagerAdapter.POSITION_NONE;
    }

    @Override
    public Fragment getItem(int position) {
        DateTime pagerdate = DateTime.now(TimeZone.getDefault());
        DateTime days = pagerdate.plusDays(position - 5000);

        Bundle bundle = new Bundle();
        bundle.putString("date", days.format("YYYY-MM-DD").toString());

        RoosterFragment roosterFragment = new RoosterFragment();
        roosterFragment.setArguments(bundle);

        return roosterFragment;
    }
}

You could fake the endlessly count with more high numbers like

  • year 0001
  • year 3999

Around the: 1.500.000 days believe me no one is gonna go this far all the way swiping!

I've tried the a lot infinite examples but this is the only working example I think!

Upvote if it worked for you and don't be shy to ask for more examples or help with your app!

However it would be cool if someone got something like a really infinte viewpager without fake counts and so on ;)

5
Kuffs On

Create a pageradapter that contains an array of the dates you want to support. You can pass this array in on the constructor.

Override getCount to return the correct number of dates in the array.

Override getItem and return a fragment from it with the date initialised based on the position parameter.