Фрагмент ViewPager NullPointer проблема

У меня есть некоторые фрагменты, которые меняются местами в моей основной деятельности. Начальный фрагмент называется 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)

Метод onCreateView для BrowseHomeFragment:

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://stackru.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 что-то теряет, хотя я запустил отладку, и это не нуль..

Я могу исправить это, просто каждый раз воссоздавая свой BrowseFragment, прежде чем заменить им активный фрагмент, но я бы предпочел просто использовать его повторно.

Буду очень признателен за любую помощь в понимании того, что именно происходит и как его решить.

1 ответ

Решение

После удара головой я нашел решение.. В моем адаптере я теперь перезаписываю onRestoreState, чтобы ничего не делать..

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

Я не уверен, что это лучшее решение, которое, по-видимому, не имеет каких-либо негативных последствий, и если кто-то может поговорить с этим "исправлением" и почему оно работает или предложить лучшее решение, это будет с благодарностью.

Другие вопросы по тегам