Бесконечный ViewPager

Это кажется возможным, но я немного затрудняюсь выяснить, как реализовать ViewPager, который может неограниченно отображаться.

Мой вариант использования - для календаря, который показывает месяц за раз, но мог бы переключиться на любой месяц с помощью пейджинга достаточно времени.

В настоящее время я просто extending PagerAdapter, и 3 пользовательских MonthViews добавляются так:

    @Override
    public Object instantiateItem(View collection, int position) {
        final MonthView mv = new MonthView(HistoryMonthActivity.this);
        mv.setLayoutParams(new ViewSwitcher.LayoutParams(
                android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                android.view.ViewGroup.LayoutParams.MATCH_PARENT));
        mv.setSelectedTime(mTime);

        ((DirectionalViewPager) collection).addView(mv, 0);

        return mv;
    }

Я хотел бы сохранить только 3 MonthView в памяти за раз, так что нет большой задержки при отображении данных из моей базы данных на каждом MonthView, когда пользователь табуляции. Поэтому каждый раз, когда отображается новая страница, мне нужно удалить один MonthView и добавить один MonthView. Если у кого-то есть лучшая идея для той же функциональности, я бы хотел ее услышать!

Я пытаюсь использовать FragmentStatePagerAdapter.

Ответ 1

Я смог реализовать это, используя небольшую магию в моих MonthView s, my PagerAdapter OnPageChangeListener, а также с редактированием исходного кода ViewPager. Если кто-то заинтересован в том, как я его достиг, проверить исходный код или прокомментировать конкретный вопрос.

Ответ 2

На самом деле, я смотрел на различные способы сделать эту "бесконечную" разбивку на страницы, и хотя человеческое понятие времени состоит в том, что оно бесконечно (хотя у нас есть понятие начала и конца времени), компьютеры имеют дело с дискретностью. Существует минимальное и максимальное время (которое можно отрегулировать с течением времени, помните, основываясь на страхе Y2K?).

В любом случае, точка этого обсуждения состоит в том, что он/должен быть достаточным для поддержки относительно бесконечного диапазона дат через фактически конечный диапазон дат. Отличным примером этого является реализация платформы Android CalendarView и WeeksAdapter внутри нее. Минимальная дата по умолчанию - 1900, а максимальная дата по умолчанию - 2100, это должно охватывать 99% использования календаря любого человека в радиусе 10 лет вокруг сегодня.

То, что они делают в своей реализации (ориентировано на недели), вычисляет количество недель между минимальной и максимальной датой. Это становится числом страниц в пейджере. Помните, что пейджер не должен поддерживать все эти страницы одновременно (setOffscreenPageLimit(int)), он просто должен иметь возможность создавать страницу на основе номера страницы (или индекса/позиции). В этом случае индекс - это количество недель, прошедших с минимальной даты. При таком подходе вам просто нужно сохранить минимальную дату и количество страниц (расстояние до максимальной даты), а затем для любой страницы вы можете легко вычислить неделю, связанную с этой страницей. Не танцует вокруг того, что ViewPager не поддерживает цикл (a.k.a бесконечная разбивка на страницы) и пытается заставить его вести себя так, как будто он может бесконечно прокручиваться.

new FragmentStatePagerAdapter(getFragmentManager()) {
    @Override
    public Fragment getItem(int index) {
        final Bundle arguments = new Bundle(getArguments());
        final Calendar temp_calendar = Calendar.getInstance();
        temp_calendar.setTimeInMillis(_minimum_date.getTimeInMillis());
        temp_calendar.setFirstDayOfWeek(_calendar.getStartOfWeek());
        temp_calendar.add(Calendar.WEEK_OF_YEAR, index);
        // Moves to the first day of this week
        temp_calendar.add(Calendar.DAY_OF_YEAR,
                -UiUtils.modulus(temp_calendar.get(Calendar.DAY_OF_WEEK) - temp_calendar.getFirstDayOfWeek(),
                7));
        arguments.putLong(KEY_DATE, temp_calendar.getTimeInMillis());
        return Fragment.instantiate(getActivity(), WeekDaysFragment.class.getName(), arguments);
    }

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

Тогда WeekDaysFragment может легко отображать неделю, начиная с даты, переданной в ее аргументах.