viewpager java.lang.IllegalArgumentException:The observer is null

Keywords: Fragment Java github Android

Recently, I had a problem with the ViewPager when I was doing vertical switching...

First of all, this vertical ViewPager is made with reference to the God on github. For GitHub address, please refer to:

https://github.com/simplezhli/ChangeTabLayout

Next, let's talk about the pit I met.
My project uses a fragment of the MVP architecture, and this Vertical View Pager is in one of the fragments. Because of the MVP architecture, the interface display is only a view loaded on the same fragment, so there is only one Base Fragment in the whole project.

When the fragment is first opened, the interface shows no problem. Then the fragment is not destroyed when it exits the fragment, but the ViewHandler on the fragment is hidden. The corresponding code in the ViewHandler is as follows:

    @Override
    public void onHiddenChanged(boolean hidden) {
        if (!hidden) {
            initData();
        } else {
            mVerticalViewPager.removeAllViews();
        }
    }

    /**
     * Initialization interface parameters
     */
    private void initData() {
        mExamId = mActivity.getIntent().getStringExtra(ConstValue.EXAM_RECORD_ID);
        mReportPresenter = new ReportPresenter(this, mActivity);
        mVerticalViewPager.post(new Runnable() {
            @Override
            public void run() {
                mReportPresenter.getFileInfo(mExamId);
            }
        });
        onSetProgressBarVisibility(View.VISIBLE);
    }
....

    @Override
    public void showWaveView(List<View> waveViews) {
        mWaveViewList = waveViews;
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(mWaveViewList);
        mVerticalViewPager.setAdapter(viewPagerAdapter);
    }

Code in BaseFragment:

 @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (null != mViewHandler) {
            mViewHandler.onHiddenChanged(hidden);
            mViewHandler.setHidden(hidden);
        }
    }

When the interface is opened again, the problem arises:

Caused by:
  java.lang.IllegalArgumentException:The observer is null.
  android.database.Observable.registerObserver(Observable.java:45)
  android.support.v4.view.PagerAdapter.registerDataSetObserver(PagerAdapter.java:296)
  rkhy.com.ecg.view.VerticalViewPager.setAdapter(VerticalViewPager.java:477)
  rkhy.com.ecg.fragment.mvp.view.impl.ReportViewHandler.showWaveView(ReportViewHandler.java:146)

From the description of the bug, it is an error in setAdapter. Find the corresponding code of VerticalViewPager as follows:

Look at the method in Pager Adapter that does not override the RegisterDataSetObserver in the custom adapter:

    /**
     * Register an observer to receive callbacks related to the adapter's data changing.
     *
     * @param observer The {@link android.database.DataSetObserver} which will receive callbacks.
     */
    public void registerDataSetObserver(DataSetObserver observer) {
        mObservable.registerObserver(observer);
    }

As you can see, updates to views in Pager Adapter use the observer pattern, where observers are registered. In my custom Vertical View Pager, because the mAdapter is not empty on the second entry, the operation of destroying the view before it is executed, but the observer is registered as null before the operation, which leads to this problem.

Solution:
1. Customized Vertical View Pager, which no longer registers the observer as null before destroying the previous view;


2. In a custom Adapter, override the registerDataSetObserver method and add a null judgment:

    @Override
    public void registerDataSetObserver(DataSetObserver observer) {
        if (null != observer) {
            super.registerDataSetObserver(observer);
        }
    }

OK, this problem is solved ~test the code again, the problem is solved.

Posted by balistic on Sun, 16 Dec 2018 21:18:04 -0800