6

I have an Activity that contains a Fragment with a ViewPager. Then I call a method of a Fragment within the ViewPager. But if that Fragment then calls getParentFragment(), it returns null.

Why is getParentFragment() null?


The main Fragment that contains a ViewPager:

public class MyFragment extends Fragment {
    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private ViewPagerAdapter mAdapter;

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        View view = getView();

        // Setup the ViewPager
        mViewPager = (ViewPager) view.findViewById(R.id.container);

        ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager(), getActivity());
        mViewPager.setAdapter(adapter);
        //setupViewPager(mViewPager);

        // Setup the TabLayout
        mTabLayout = (TabLayout) view.findViewById(R.id.tabs);
        mTabLayout.setupWithViewPager(mViewPager);
    }

    // This method is called from Activity.
    public void callNestedFragment() {
        if (isDetached()) {
            return;
        }

        // This fragment cannot be null, because it doesn't crash here. (this is just a sample).
        ((Fragment0) mViewPager.getItem(0)).testMethod();
    }
}

The nested Fragment (inside mViewPager):

public class Fragment0 extends Fragment {

    ...

    public void testMethod() {
        if (isDetached()) {
            return;
        }

        // Why is getParentFragment() null? This is the log: "Parent fragment: null"
        Log.i(TAG, "Parent fragment: " + getParentFragment());
        return;
    }
}

The ViewPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {
    private Context mContext;

    public ViewPagerAdapter(FragmentManager manager, Context context) {
        super(manager);
        mContext = context;
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new Fragment0();
            case 1:
                return new Fragment1();
            case 2:
                return new Fragment2();
            case 3:
                return new Fragment3();
            case 4:
                return new Fragment4();
        }

        return null;
    }

    @Override
    public int getCount() {
        return 5;
    }
}

If more code is needed, please let me know. Thanks for your help.

Thomas Vos
  • 12,271
  • 5
  • 33
  • 71
  • Which fragment do you call? That fragment could be null. Keep in mind that view page inits only +/-1 fragments from current visible one. – Cătălin Florescu Oct 23 '16 at 20:01
  • When and where do you call testMethod? – Ahmed Ghonim Oct 23 '16 at 20:03
  • @FlorescuGeorgeCătălin I know, but if the fragment is null, how is it possible that it didn't crash, and I still see the log? It passes the `isDetached()` check. – Thomas Vos Oct 24 '16 at 06:19
  • @AhmedGhonim The method `testMethod()` is called by `MyFragment`, after it has been attached. – Thomas Vos Oct 24 '16 at 06:21
  • I think is because not throwing any exception, just logging. – Cătălin Florescu Oct 24 '16 at 06:46
  • @FlorescuGeorgeCătălin The fragment can't be null, then it would have crashed on this line: `((Fragment0) mViewPager.getItem(0)).testMethod();`. If it was null, and it somehow didn't crash, why am I still seeing the following in the log: `Parent fragment: null` – Thomas Vos Oct 24 '16 at 06:57
  • Thats why i asked which is the called fragment. Please add setupViewPager method in this post. I think there is your problem. Do you use fragment manager or child fragment manager? – Cătălin Florescu Oct 24 '16 at 07:37
  • @FlorescuGeorgeCătălin child fragment manager. Please see edit. – Thomas Vos Oct 24 '16 at 07:42
  • When you call test method? Probably fragment isn't fully created. PS: you should move initialization code inside onViewCreated method because view is returned there, not in onActivityCreated. – Cătălin Florescu Oct 24 '16 at 07:50
  • @FlorescuGeorgeCătălin You're right! The fragment is not fully created. The method `callNestedFragment()` is called by Activity when the app has scanned all music files on the device. That happens somewhere after `onStart()`. But why doesn't the Fragment return after `isDetached()`? PS: `onActivityCreated()` is called after `onViewCreated()`. – Thomas Vos Oct 24 '16 at 07:54
  • I think is because isDetached() is set to true when fragment has started process of creation. I don't know, Google code.. – Cătălin Florescu Oct 24 '16 at 07:58
  • Please check [this](http://stackoverflow.com/a/40971278/3836137) answer Hope this helps ... – Ameen Maheen Dec 05 '16 at 10:01

2 Answers2

3

In my case , I was using FragmentManager instead of ChildFragmentManager which was causing this issue.

user2991413
  • 521
  • 2
  • 9
  • 26
  • Oh my god. You are so genius. I changed "getFragmentManager()" to "getChildFragmentManager()" in my parent fragment when replacing to child fragment. It solved my problem. – mazend Nov 01 '19 at 10:00
0

I found the answer. If isDetached() is true, it doesn't mean getParentFragment() is not null.

So instead of the previous check in testMethod(), this is the new code:

public void testMethod() {
    if (isDetached() && getParentFragment() != null) {
        return;
    }

    ...
}

I also now call the same method again in the onStart() method within Fragment0, where getParentFragment() should not be null.

Thomas Vos
  • 12,271
  • 5
  • 33
  • 71