片段ViewPager NullPointer问题

eri*_*rik 1 android android-fragments fragmentmanager

我有一些片段被交换进我的主要活动.初始片段称为BrowseHomeFragment并且最初加载正常,但是当我用新片段替换它然后将其替换回来时我得到以下错误

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.util.ArrayList.size()' on a null object reference
    at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:686)
    at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:215)
    at android.support.v4.view.ViewPager.setAdapter(ViewPager.java:536)
Run Code Online (Sandbox Code Playgroud)

BrowseHomeFragment的onCreateView方法:

public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
        InjectionGraph.inject(this);

        View view = inflater.inflate(R.layout.fragment_browse, container, false);
        ButterKnife.inject(this, view);

        addTabsToPagerSlidingTabStrip(inflater);

        viewPager.setAdapter(new BrowseHomePagerAdapter(getChildFragmentManager()));

        pagerSlidingTabStrip.setViewPager(viewPager);
        // has to set page change listener in indicator
        pagerSlidingTabStrip.setOnPageChangeListener(pageChangeListener);

        viewPager.setCurrentItem(initialTabIndex);

        return view;
    }
Run Code Online (Sandbox Code Playgroud)

BrowseHomePagerAdapter

public class BrowseHomePagerAdapter extends FragmentStatePagerAdapter {
    private int lastPosition = -1;

    @Inject
    BrowseHomepageMetricRecorder browseHomepageMetricRecorder;

    @Inject
    NetworkMonitor networkMonitor;


    /**
     * For explanation on why Fragment references are cached, please refer to
     * http://stackoverflow.com/questions/8785221/retrieve-a-fragment-from-a-viewpager
     */
    final SparseArray<Fragment> registeredFragments = new SparseArray<>();


    public BrowseHomePagerAdapter(FragmentManager fm) {
        super(fm);
        InjectionGraph.inject(this);

    }


    @Override
    public Fragment getItem(int i) {

        switch (BrowseHomeFragment.Tab.resolve(i)) {
        // TODO: connect category, favorite, and downloaded list fragments
        case Categories:
            return new CategoryHomePageFragment();
        case Downloaded:
            return new OfflineContentFragment();
        default:
            return new ComingSoonFragment();
        }
    }


    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }


    @Override
    public int getCount() {
        return BrowseHomeFragment.Tab.values().length;
    }


    @Override
    public CharSequence getPageTitle(int position) {
        return BrowseHomeFragment.Tab.resolve(position).name();
    }


    @Override
    public void setPrimaryItem(ViewGroup container, int position, Object object) {
        if (position != lastPosition) { // debounce Android's redundant calls
            switch (BrowseHomeFragment.Tab.resolve(position)) {
                case Categories:
                    browseHomepageMetricRecorder.recordGotoCategoriesMetric();
                    if (!networkMonitor.isDeviceConnected()) {
                        networkMonitor.postUserActionRequiresConnectivityEvent();
                    }
                    break;
                case Downloaded:
                    browseHomepageMetricRecorder.recordGotoDownloadedMetric();
                    break;
                default:
                    break;
            }
            lastPosition = position;
        }

        super.setPrimaryItem(container, position, object);
    }


    public Object instantiateItem(ViewGroup container, int position) {
        final Fragment fragment = (Fragment) super.instantiateItem(container, position);
        registeredFragments.put(position, fragment);
        return fragment;
    }


    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        registeredFragments.remove(position);
        super.destroyItem(container, position, object);
    }


    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
Run Code Online (Sandbox Code Playgroud)

我收集到viewPager失去了一些东西,虽然我已经运行调试,它不是null.

我可以通过在每次用它替换活动片段之前重新创建我的BrowseFragment来解决这个问题,但我宁愿只能重用它.

任何帮助了解究竟发生了什么以及如何解决它将不胜感激.

eri*_*rik 5

在敲打我的头后,我找到了一个解决方案..在我的适配器中,我现在重写onRestoreState什么都不做..

@Override
public void restoreState(Parcelable state, ClassLoader loader) {
     //Do NOTHING;
}
Run Code Online (Sandbox Code Playgroud)

我不确定这是否是最好的解决方案,似乎没有任何不良影响,如果有人可以说这个"修复"以及它为什么工作或提供更好的解决方案,我将不胜感激.