“I always say, 'This will be my last 'Metal Gear.'” Hideo Kojima

(Another way of) Updating a ListView inside a Fragment placed on a ViewPager on DialogFragment dismiss

Hi again!

This is a quick post related to the previous post. Take a look at it if you don’t know what I’m talking about.

Why do we need another method?

I found that sometimes the method explained there will not work. So I decided to investigate deeper, and I found another way to build things up that works even better.

Basically, extend your PagerAdapter from FragmentStatePagerAdapter (it may work with FragmentPagerAdapter, but didn’t to me). Override any method you need and put an array, as we did in the other post. We will “remember” our fragments. Then, we will override instantiateItem() on our adapter. This is the main change between the two methods. Instead of registering our fragments on getItem (), we do it on instantiateItem().

Explain.

If you register your fragments on an array while in getItem() you may find later with a NullPointerException while trying to get a reference to any fragment from the ViewPager. This is because getItem() is usually where devs (we did in last post) initialize fragments; but it’s not where Android will go while recreating UI. So, you may get a NullPointerException because Android has destroyed your fragment or is not using that instance anymore.

Registering them on instantiateItem() will “refresh” the array correctly, and you will be able to retrieve fragments from the ViewPager. So, override these methods on your adapter:

    ...
    SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

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

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

    public Fragment getRegisteredFragment(int position) {
        return registeredFragments.get(position);
    }
   ...

Then, in your Activity you can retrieve the desired fragment by position. For example, following the previous post method, you can do this on your onDBChanged() method:

    @Override
    public void onDBChanged() {
        int index = mViewPager.getCurrentItem();
        MyPagerAdapter mAdapter = ((MyPagerAdapter)mViewPager.getAdapter());
        ScheduleFragment scheduleFragment =
            (ScheduleFragment)mAdapter.getRegisteredFragment(index);
        scheduleFragment.updateDB();
    }

And that’s it! Hope it helped : )

Jordi.

See also: