Android中的自定义日历视图

bma*_*mat 5 android android-layout android-viewpager

我正在为我的Android应用程序构建自定义日历视图,使您可以在几个月之间滑动。我已经创建了自定义日历正方形视图,并将其嵌入到自定义日历视图中,并且一切都可以在1个月的比例上完美运行。

不幸的是,现在我被困住了。现在,我想将自定义日历月视图嵌入到无限视图分页器中,以便可以无限期地前后滚动日历。

我尝试通过使用一个简单的技巧将此水平寻呼机调整为无限滚动。我持有3个日历月视图数组,并根据用户滚动到的位置更新列表。例...

  1. [7月,8月,9月](焦点位于8月,然后用户滑动到9月)
  2. [7月,8月,9月 ](现在是9月)
  3. [ 8月,8月,9月 ](将8月左移一位,覆盖7月)
  4. [8月,9月9月 ](将9月左移一位,覆盖8月)
  5. [8月,9月,9月](将视图设置为9月中旬,因此我们再次居中)
  6. [8月,9月10月 ](用实际的下个月覆盖9月2日)

不过,当我执行此操作时,刷到下个月时屏幕上会出现明显的闪烁。

这是向前滚动的代码(注意:向后滚动有相同的问题)

private void updateViewsForForwardScroll() {
    // Note: INDEX_PREV = 0; INDEX_CURR = 1; INDEX_NEXT = 2
    ((CalendarMonthView) getChildAt(INDEX_PREV)).showMonth(oneMonthPriorTo(currentMonth));
    ((CalendarMonthView) getChildAt(INDEX_CURR)).showMonth(currentMonth);
    setCurrentScreen(INDEX_CURR, false);
    ((CalendarMonthView) getChildAt(INDEX_NEXT)).showMonth(oneMonthAfter(currentMonth));
}
Run Code Online (Sandbox Code Playgroud)

我认为问题在于setCurrentScreen()在showMonth(currentMonth)之前完成,因此在设置屏幕时,INDEX_CURR上的视图仍在更新。我尝试通过使用以下策略来解决此问题...

  1. [7月,8月,9月](焦点位于8月,然后用户滑动到9月)
  2. [7月,8月,9月 ](现在是9月)
  3. [8月,9月 ](7月删除,但将其存储以进行回收)
  4. [8月,9月,10月](回收7月以代替显示10月,并添加视图)

我完全没有触摸当前聚焦的视图,但是仍然有闪光!这次,屏幕从9月闪烁到8月,然后又回到9月。

我在做什么错?有没有办法在用户不知情的情况下做我想做的事情?如果没有,我可以利用现有的课程吗?

(作为附带的问题,我可以通过任何方式直观地自定义Android CalendarView吗?这真的可以解决我的所有问题...)

提前致谢!

bma*_*mat 1

我最终通过扩展FragmentStatePagerAdapter并集成 user113215 的建议来使其工作。我并没有追求真正的无限滚动,而是几乎无限(即 10,000 个月,或 833 年)。这是我的大部分代码:

public static class CalendarAdapter extends FragmentStatePagerAdapter {
    private static final int NUM_MONTHS = 10000;
    private static final int INDEX_EPOCH = NUM_MONTHS/2;
    private static final int MONTHS_PER_YEAR = 12;
    private static final Calendar calendarMonthEpoch = new GregorianCalendar(2012, Calendar.AUGUST, 1);

    // ...

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

    @Override
    public Fragment getItem(int position) {
        return CalendarMonthFragment.newInstance(calendarMonthAtPosition(position));
    }

    private static Calendar calendarMonthAtPosition(int position) {
        int offset = position - INDEX_EPOCH;
        Calendar calMonthAtPosition = (Calendar) calendarMonthEpoch.clone(); 
        calMonthAtPosition.add(Calendar.MONTH, offset % MONTHS_PER_YEAR);
        calMonthAtPosition.add(Calendar.YEAR, offset / MONTHS_PER_YEAR);

        return calMonthAtPosition;
    }

    // ...

}
Run Code Online (Sandbox Code Playgroud)