ViewPager的无尽PageAdapter需要几个世纪来加载新页面

时间:2016-04-20 16:30:31

标签: android android-viewpager

我正在尝试实施Google日历所具有的类似功能。

基本上,我有两种观点:

  • 查看A) 带有CustomViews日历的ViewPager。我们将此MonthViewPager称为ViewPager
  • 查看B) - 在ViewPager的顶部 - 年份视图,其中显示View A)必须去的月份。我们称之为YearView

范围:我希望用户能够“无限”地滚动所需的月份,并且能够从YearView切换月份。

我初始化ViewPager的方式是:

public MonthViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context = context;
    this.attrs = attrs;
    setAdapter(new EndLessAdapter(Calendar.getInstance()));
    setCurrentItem(Integer.MAX_VALUE / 2);
}

取得了这种表现:

enter image description here

我一直在使用setOffscreenPageLimit(int limit)将处于空闲状态的屏幕保留在屏幕上。我试过1,3,12 ......

我的PagerAdapter就是这个:

public class EndLessAdapter extends PagerAdapter {

    Calendar calendar;
    public EndLessAdapter(Calendar calendar) {
        this.calendar = calendar;
    }

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

    @Override
    public CalendarView instantiateItem(ViewGroup collection, int position) {

        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + position - Integer.MAX_VALUE/2);

        final CalendarView calendarView = new CalendarView(context, attrs);
        ((ViewPager) collection).addView(calendarView, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));


        return calendarView;
    }

    @Override
    public void destroyItem(ViewGroup arg0, int arg1, Object arg2) {
        ((ViewPager) arg0).removeView((View) arg2);
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        return arg0 == ((View) arg1);
    }

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

}

但是当我想从YearView设置一个月(例如12月)时,如果您看到我的适配器,我会设置8 + Integer.MAX_VALUE / 2的位置8 + April

我这样做:

    int differenceMonths = Utils.differenceMonthsToNow(date);
    monthViewPager.setCurrentItem(differenceMonths + Integer.MAX_VALUE / 2, false);

这就是表现:

enter image description here

UI一直被阻止。

我使用Android Monitor调试了所有内容,我看到99.0%的时间都在花时间:

ViewPager.setCurrentItem(int item, boolean smoothScroll)

enter image description here

并且方法instantiateItem正在调用每个视图。 (我认为不应该是这样,也许这是一个错误)。

  • 或者,我尝试将所有内容嵌入Fragment并将PageAdapter更改为FragmentStatePagerAdapter,但结果非常相似。

我的代码发生了什么?是不是可以跳过,例如,1000页而不避免画每一页?

感谢您完整阅读;)。

1 个答案:

答案 0 :(得分:1)

setCurrentItem(int)使用平滑滚动,这意味着它将滚动浏览所有视图,直到它到达您要求的视图,这意味着必须绘制所有视图。

  

是否可以跳过,例如,1000页而不避免画每一页?

嗯,这里的解决方案是在没有滚动的情况下进行,setCurrentItem(int, false);这样ViewPager只会绘制该项并跳过中间的所有项目。

希望它有所帮助。