片段ViewPager NullPointer问题

时间:2017-01-31 20:55:28

标签: 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)

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;
    }

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);
    }

我认为viewPager失去了一些东西虽然我已经运行了调试而且它不是null ..

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

任何帮助,了解究竟发生了什么以及如何解决它将非常感激。

1 个答案:

答案 0 :(得分:5)

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

@Override
public void restoreState(Parcelable state, ClassLoader loader) {
     //Do NOTHING;
}

我不确定这是否是最好的解决方案,似乎没有任何不良影响,如果有人能够对此发表意见,那么#34;修复&#34;为什么它的工作原理或提供更好的解决方案,我们将不胜感激。