View incorrectly adds to Viewpager and onPageScroll error

I am getting error indexOutOfBoundException

on onpageScrollchange

. How I traced the error. This is a nullPointer exception for rightMonth

inonPageScrollStateChanged

Correct me if I am wrong. The viewpager can have two pages at a time. More than two pages have to be processed at runtime.

private final class IndicatorPageChangeListener implements OnPageChangeListener
{
    private final TitlePageIndicator indicator;

    private IndicatorPageChangeListener(TitlePageIndicator indicator)
    {
        this.indicator = indicator;
    }

    @Override
    public void onPageScrolled(int position , float positionOffset , int positionOffsetPixels)
    {
    }

    @Override
    public void onPageScrollStateChanged(int state)
    {
        if (state == ViewPager.SCROLL_STATE_IDLE)
        {
            MonthView leftMonth = (MonthView) monthPager.getChildAt(0);
            MonthView centerMonth = (MonthView) monthPager.getChildAt(1);
            MonthView rightMonth = (MonthView) monthPager.getChildAt(2);//this is null

            final Time oldCenterTime = new Time(centerMonth.getTime());

            String[] newTitles = new String[3];

            int focusedPage = HistoryMonthFragment.this.focusedPage;

            if (focusedPage == 0)
            {
                final Time oldTopTime = new Time(leftMonth.getTime());

                final Time time = new Time(oldTopTime);
                time.month--;
                time.normalize(true);

                // TODO: load and switch shown events
                leftMonth.setTime(time);
                centerMonth.setTime(oldTopTime);
                rightMonth.setTime(oldCenterTime);
            }
            else if (focusedPage == 2)
            {
                final Time oldBottomTime = new Time(rightMonth.getTime());

                final Time time = new Time(oldBottomTime);
                time.month++;
                time.normalize(true);

                leftMonth.setTime(oldCenterTime);
                centerMonth.setTime(oldBottomTime);
                rightMonth.setTime(time);
            }

            Activity a = getActivity();
            newTitles[0] = Utils.formatMonthYear(a, leftMonth.getTime());
            newTitles[1] = Utils.formatMonthYear(a, centerMonth.getTime());
            newTitles[2] = Utils.formatMonthYear(a, rightMonth.getTime());

            monthAdapter.setTitles(newTitles);

            // always set to middle page to continue to be able to
            // scroll up/down
            indicator.setCurrentItem(1, false);

            eventsChanged(focusedPage);
        }
    }

    @Override
    public void onPageSelected(int position)
    {
        focusedPage = position;
    }
}

      

And onCreateView

@Override
public View onCreateView(LayoutInflater inflater , ViewGroup container ,
        Bundle savedInstanceState)
{
    getSherlockActivity().setSupportProgressBarIndeterminateVisibility(true);
    View root = inflater.inflate(R.layout.fragment_history_month, container, false);

    // Get first day of week based on locale and populate the day headers
    startDay = Calendar.getInstance().getFirstDayOfWeek();
    final int diff = startDay - Calendar.SUNDAY - 1;
    final int startDay = Utils.getFirstDayOfWeek();

    for (int day = 0; day < 7; day++)
    {
        final String dayString = DateUtils.getDayOfWeekString(
                (DAY_OF_WEEK_KINDS[day] + diff) % 7 + 1, DateUtils.LENGTH_MEDIUM);
        final TextView label = (TextView) root.findViewById(DAY_OF_WEEK_LABEL_IDS[day]);
        label.setText(dayString);
    }

    monthAdapter = new MonthPagerAdapter();
    monthPager = (ViewPager) root.findViewById(R.id.monthpager);

    monthPager.setOffscreenPageLimit(3);

    monthPager.setAdapter(monthAdapter);

    final TitlePageIndicator indicator = (TitlePageIndicator) root.findViewById(R.id.indicator);
    indicator.setFooterColor(getResources().getColor(R.color.primary1));
    indicator.setViewPager(monthPager, 2);
    indicator.setOnPageChangeListener(new IndicatorPageChangeListener(indicator));

    return root;
}

      

After googling I added monthPager.setOffscreenPageLimit(3); in onCreate();

And all my fragments are working fine when trying

indicator.setViewPager(monthPager,0)://i have tried for 0,1,2 all are working.

      

But when OnPageScroll happens it gives error IndexOutOfBoundError.

And then I tried different ways to add c ontainer.addView(mv, position); on MonthPagerAdapter.

MonthPagerAdapter

 private class MonthPagerAdapter extends PagerAdapter implements TitleProvider
    {
        private String[] titles = new String[] { "", "", "" };

        public String[] getTitles()
        {
            return titles;
        }

        public void setTitles(String[] titles)
        {
            this.titles = titles.clone();
        }

        public MonthView addMonthViewAt(ViewPager container , int position , Time time)
        {
            final MonthView mv = new MonthView(HistoryMonthFragment.this);
            mv.setLayoutParams(new ViewSwitcher.LayoutParams(
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                    android.view.ViewGroup.LayoutParams.MATCH_PARENT));
            mv.setSelectedTime(time);

            //container.addView(mv, position);
            //((ViewPager) container).addView(mv, 0);
            container.addView(mv,container.getChildCount()> position ? position : ((ViewPager)container).getChildCount());
            //((ViewPager)collection).addView(layout, ((ViewPager)collection).getChildCount() > position ? position : ((ViewPager)collection).getChildCount())

            return mv;
        }

        @Override
        public void destroyItem(View container , int position , Object object)
        {
            // simply reuse items...
            // ((ViewPager) container).removeViewAt(position);
        }

        @Override
        public int getCount()
        {
            return titles.length;
        }

        @Override
        public String getTitle(int position)
        {
            String title = titles[position];
            return title;
        }

        @Override
        public Object instantiateItem(View container , int position)
        {
            MonthView childAt = (MonthView) ((ViewPager) container).getChildAt(position);

            if (childAt == null)
            {
                final Time time = new Time();
                time.setToNow();

                // set to first day in month. this prevents errors when the
                // current
                // month (TODAY) has more days than the neighbor month.
                time.set(1, time.month, time.year);
                time.month += (position - 1); // add the offset from the center
                                                // time
                time.normalize(true);

                MonthView mv = addMonthViewAt((ViewPager) container, position, time);

                titles[position] = Utils.formatMonthYear(getActivity(), mv.getTime());

                return mv;
            }
            return childAt;
        }

        @Override
        public boolean isViewFromObject(View view , Object object)
        {
            return view == object;
        }

        @Override
        public void restoreState(Parcelable state , ClassLoader loader)
        {
        }

        @Override
        public Parcelable saveState()
        {
            return null;
        }

        @Override
        public void startUpdate(View container)
        {
        }

        boolean alreadyLoaded = false;

        @Override
        public void finishUpdate(View container)
        {
            if (!alreadyLoaded && ((ViewPager) container).getChildCount() == getCount())
            {
                ((HostActivity) getActivity()).getSupportLoaderManager().getLoader(0).forceLoad();
                alreadyLoaded = true;
            }
        }
    }

      

I think the problem is somewhere in the instantiateItem.

+3


source to share





All Articles