简体   繁体   English

当用户到达ViewPager的末尾时,如何动态添加片段以启动ViewPager?

[英]How do I dynamically add fragments to start of ViewPager as user reaches the end of the ViewPager?

I currently have a basic ViewPager that utilizes a FragmentStatePagerAdapter to initialize fragments. 我目前有一个基本的ViewPager ,它利用FragmentStatePagerAdapter来初始化片段。

This ViewPager starts at the end and scrolls backwards (ie scrolls to the left). ViewPager从最后开始向后滚动(即向左滚动)。

As the user nears the start of the ViewPager 's list, I want there to be more items added to the start of the adapter's list programmatically, essentially creating an infinitely scrollable ViewPager (going left) without disrupting the user's experience (ie not reloading their current fragment as the ViewPager has fragments added on to it). 当用户接近ViewPager列表的开头时,我希望以编程方式将更多项添加到适配器列表的开头,实质上创建一个无限可滚动的ViewPager (向左)而不会破坏用户的体验(即不重新加载他们的当前片段作为ViewPager添加了片段)。 However, I am unable to accomplish this. 但是,我无法做到这一点。

Currently, I am detecting when my adapter's getItem() function passes a position of 0, populating the start of the list the adapter uses with more items, and then calling notifyDataSetChanged() . 目前,我正在检测我的适配器的getItem()函数何时传递位置0,填充适配器使用更多项的列表的开头,然后调用notifyDataSetChanged() However, what happens is that the fragments at position 1 (which triggers the getItem() call as soon as it comes into focus) and 0 remain at the start of the ViewPager and the new fragments are loaded all out of order. 但是,发生的情况是位置1处的片段(一旦它进入焦点就会触发getItem()调用)并且0保留在ViewPager的开头,并且新片段全部无序地加载。

Here is my FragmentStatePagerAdapter : 这是我的FragmentStatePagerAdapter

class WeekyMoodFragmentAdapter extends FragmentStatePagerAdapter {

    private final int NUM_WEEKS_TO_INITIALIZE = 4;
    private final List<Long> timestampList = new ArrayList<>();
    private final ViewPager mViewPager;

    WeekyMoodFragmentAdapter(FragmentManager fragmentManager, ViewPager viewPager) {
        super(fragmentManager);

        mViewPager = viewPager;
        initializeTimestampList();
    }

    private void initializeTimestampList() {

        DateTime mondayOfThisWeek = new DateTime(System.currentTimeMillis());
        while (mondayOfThisWeek.getDayOfWeek() != DateTimeConstants.MONDAY) {
            mondayOfThisWeek = new DateTime(mondayOfThisWeek.getMillis()
                    - TimeUnit.HOURS.toMillis(DateTimeConstants.HOURS_PER_DAY));
        }

        long weekStartMS = mondayOfThisWeek.withTimeAtStartOfDay().getMillis()
                - TimeUnit.DAYS.toMillis(DateTimeConstants.DAYS_PER_WEEK * NUM_WEEKS_TO_INITIALIZE);

        addTimestampsToList(weekStartMS);
    }

    private void addTimestampsToList(long weekStartMS) {
        for (int i = 0; i < NUM_WEEKS_TO_INITIALIZE; ++i) {
            weekStartMS += TimeUnit.DAYS.toMillis(DateTimeConstants.DAYS_PER_WEEK);

            timestampList.add(i, weekStartMS);
        }
        notifyDataSetChanged();
    }

    @Override
    public Fragment getItem(int position) {
        Fragment fragment = WeeklyMoodFragment.newInstance(timestampList.get(position));
        if (position == 0) {
            addTimestampsToList(timestampList.get(position)
                    - TimeUnit.DAYS.toMillis
                    (DateTimeConstants.DAYS_PER_WEEK * (NUM_WEEKS_TO_INITIALIZE+1)));
        }
        return fragment;
    }

    @Override
    public int getCount() {
        return timestampList.size();
    }
}

And how I initialize my ViewPager : 以及我如何初始化我的ViewPager

ViewPager moodViewPager = (ViewPager) view.findViewById(R.id.weeklyMoodViewPager);

moodViewPager.setAdapter(new WeekyMoodFragmentAdapter(getChildFragmentManager());
moodViewPager.setCurrentItem(moodViewPager.getAdapter().getCount());

have you considered a bit hacky way with getCount() returning Integer.MAX_VALUE and newInstance created from timestampList.get(position%timestampList.size()) ? 你有没有考虑过getCount()返回从timestampList.get(position%timestampList.size())创建的Integer.MAX_VALUEnewInstance getCount()有点hacky的方法? and set initial page setCurrentItem as Integer.MAX_VALUE/2 or nearest appriopiate 并将初始页面setCurrentItem设置为Integer.MAX_VALUE/2或最近的appriopiate

@Override
public Fragment getItem(int position) {
    return WeeklyMoodFragment.newInstance(
        timestampList.get(position % timestampList.size()));
        //                         ^  here important
}

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

    ...

moodViewPager.setCurrentItem(Integer.MAX_VALUE/2);
//or 
WeekyMoodFragmentAdapteradapter = new WeekyMoodFragmentAdapter(getChildFragmentManager());
moodViewPager.setAdapter(adapter);
//dividing integers will round
int roundedCount = (Integer.MAX_VALUE/2) / adapter.getCount();
moodViewPager.setCurrentItem(roundedCount * adapter.getCount())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM