1

I'm implementing an endless FragmentStatePagerAdapter to show months. I already seen some links on SO about the content:

Calendar and PagerAdapter - Unlimited Views

Infinite ViewPager

I believe on both questions there are many changes to get the result. My will is to get the same results with less code.

The first class below is my adapter based on FragmentStatePagerAdapter:

class CalendarAdapter extends FragmentStatePagerAdapter {
    private ViewPager viewPager;
    private Calendar calendar = Calendar.getInstance();

public CalendarAdapter(FragmentManager fm) {
    super(fm);
}

public void setViewPager( ViewPager viewPager ){
    this.viewPager = viewPager;
}

@Override
public Fragment getItem( int position ) {
    MonthFragment month = null;
    if( position == viewPager.getCurrentItem() ) {
        month = createMonth( 0 );
        Log.d( "DEBUG", "NO POSITION: " );
    }
    else if( position < viewPager.getCurrentItem() ) {
        month = createMonth( -1 );
        Log.d( "DEBUG", "LESS POSITION: " );
    }
    else if( position > viewPager.getCurrentItem() ) {
        month = createMonth( 1 );
        Log.d( "DEBUG", "MORE POSITION: " );
    }

    return month;
}

@Override
public int getCount() {
    return Integer.MAX_VALUE;
}

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

private MonthFragment createMonth( int whatPosition ){
    Bundle bundle = new Bundle();
    bundle.putInt( "calendarPosition", whatPosition );
    MonthFragment month = new MonthFragment();
    month.setCalendar( calendar );
    month.setArguments( bundle );
    return month;
}

And this is the code related to month based on Fragment:

public class MonthFragment extends Fragment {
private Calendar calendar;
private String[] months = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" };
private String dateFormat = "yyyy";
private TextView monthAndYear;
private GridView monthDays;
private int monthColsAndRows, calendarPosistion, currentMonth;

@Override
public void onCreate( Bundle savedInstanceState ) {
    super.onCreate( savedInstanceState );
    //Calendar has 7 columns and six rows
    monthColsAndRows = 7 * 6;
    Bundle args  = getArguments();
    calendarPosistion = args.getInt( "calendarPosition" );
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState ){
    calendar.set( Calendar.HOUR_OF_DAY, 0 );
    calendar.set( Calendar.MINUTE, 0 );
    calendar.set( Calendar.SECOND, 0 );
    calendar.set( Calendar.MILLISECOND, 0 );

    View view    = ( View ) inflater.inflate( R.layout.month_fragment, parent, false );
    monthAndYear = ( TextView ) view.findViewById( R.id.month_and_year );
    monthDays    = ( GridView ) view.findViewById( R.id.month_days );
    fillCalendar();
    return view;
}

public void setCalendar( Calendar calendar ){
    this.calendar = calendar;
}

private void fillCalendar(){
    ArrayList<Date> days = new ArrayList<>();

    Calendar tempCalendar = ( Calendar )calendar.clone();

    tempCalendar.set( Calendar.DAY_OF_MONTH, 1 );
    tempCalendar.add( Calendar.DAY_OF_MONTH, -( tempCalendar.get( Calendar.DAY_OF_WEEK ) -1 ) );

    tempCalendar.setTimeInMillis( calendar.getTimeInMillis() );

    currentMonth = tempCalendar.get( Calendar.MONTH ) + 1;

    while( days.size() < monthColsAndRows ){
        days.add( tempCalendar.getTime() );
        tempCalendar.add( Calendar.DAY_OF_MONTH, 1 );
    }

    int monthPos = tempCalendar.get( Calendar.MONTH ) - 1 < 0 ? 0 : tempCalendar.get( Calendar.MONTH ) - 1;

    //Log.e( "ERROR", "MONTH POS: "+monthPos);

    monthAndYear.setText( months[ monthPos ] + "/" + calendar.get( Calendar.YEAR ) );
    monthDays.setAdapter( new DaysAdapter( getContext(), days ) );
}

private class DaysAdapter extends ArrayAdapter< Date > {
    //Irrelevant to the question, code ommited
    ...
}

}

Some issues are occuring:

  • getItem method from adapter is called twice when it starts;

  • very next month after first one remains the same. It doesn't increment;

  • I can go forward with months. But going back indefinitely not. It locks on position 0;

EDIT: the first issue is related to the own nature of adapter. To provide smooth transitions it create the first view and very next cached view.

Community
  • 1
  • 1
learner
  • 1,222
  • 2
  • 15
  • 35

0 Answers0