findFragmentById always returns null

AndroidAndroid Fragments

Android Problem Overview


I'm defining an ID for my fragment in the xml layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/test_fragment"
...

Then I add this fragment in the activity's onCreate method:

MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, myFragment);
fragmentTransaction.commit();

This is all working fine. Replacing fragments and is also working.

Later I'm trying to retrieve this fragment by its ID in one of the activity's methods:

MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.test_fragment);

Doing so leads to myFragment being null. Always.

When I try to do the same with tags instead of IDs I can retrieve the fragment by its tag without any problems:

MyFragment myFragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, myFragment, "testfragment");
fragmentTransaction.commit();

...

MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentByTag("testfragment");

Why can't findFragmentById find the fragment, but findFragmentByTag does so? Am I missing something?

Android Solutions


Solution 1 - Android

R.id.test_fragment is not the ID of your fragment but the id of your LinearLayout

Calling add(int containerViewId, Fragment fragment) will add a fragment without a tag. So or you use add(int containerViewId, Fragment fragment, String tag) and you get back your fragment using your tag (as an ID)

Solution 2 - Android

Use the <FrameLayout> tag as a container in your layout file. Later to replace the fragments from your activity dynamically, you can use the ID of the <FrameLayout> container to replace the fragments in your activity.

<FrameLayout
            android:id="@+id/test_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

Solution 3 - Android

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/test_fragment"

it should be a fragment not a LinearLayout

<fragment android:name="com.example.yourfragment"
            android:id="@+id/test_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

Solution 4 - Android

I was using android.support.v4.app.Fragment in my layout while calling getFragmentManager() which actually searched for android.app.Fragment subclasses and I got null. So the fix was to call getSupportFragmentManager() instead.

In general make sure the package of a fragment you are subclassing and using in your layout is the same returned by the corresponding FragmentManager which performs search.

Solution 5 - Android

R.id.test_fragment is your LinearLayout ID not your Fragment.

You can define and id on a fragment when it is inflated from an xml like in this sample http://developer.android.com/guide/topics/fundamentals/fragments.html#Adding

Solution 6 - Android

Or, you should have instead used :

(MyFragment) getFragmentManager().findFragmentById(R.id.fragment_container);

Solution 7 - Android

The reasons mentioned above are valid but another possible reason is that you are trying to search for the fragment while being in a fragment this also results in fragmentManager.findFragmentById to return null. We should use childFragmentManager.findFragmentById to find the fragment inside a fragment. According to the official documentation.

public final androidx.fragment.app.FragmentManager getChildFragmentManager()

> Return a private FragmentManager for placing and managing Fragments > inside of this Fragment.

Solution 8 - Android

FragmentB fragmentB = 
(FragmentB) getSupportFragmentManager().findFragmentById(R.id.containerb);
        
if(fragmentB != null)
{
   fragmentB.showuserResponse(msg);
}

Use container id as fragment id. And then check for null reference.

Solution 9 - Android

>fragmentTransaction.add(R.id.fragment_container, myFragment); > >MyFragment myFragment = (MyFragment) getFragmentManager().findFragmentById(R.id.test_fragment);

Please notice the difference.

You should pass R.id.fragment_container as the argument to findFragmentById, as you pass it to the add function, instead of R.id.test_fragment

By the way , according to the inner implementation of the two functions, it should be right that the id can be that of its container view.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionViperView Question on Stackoverflow
Solution 1 - AndroidStErMiView Answer on Stackoverflow
Solution 2 - AndroidAmit BhandariView Answer on Stackoverflow
Solution 3 - AndroidBlackbeltView Answer on Stackoverflow
Solution 4 - Androidvir usView Answer on Stackoverflow
Solution 5 - AndroidGBoueratView Answer on Stackoverflow
Solution 6 - Androiduser2168109View Answer on Stackoverflow
Solution 7 - AndroidAbdul Rahman ShamairView Answer on Stackoverflow
Solution 8 - AndroidAman SrivastavaView Answer on Stackoverflow
Solution 9 - AndroidsuitianshiView Answer on Stackoverflow