38

When I call findFragmentById() with the id of my fragment, it returns null.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

        <fragment android:name="com.madduck.test.app.fragment.MainFragment"
                  android:id="@+id/main_fragment"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />

        <fragment android:name="com.madduck.test.app.fragment.LoginFragment"
                  android:id="@+id/login_fragment"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
</LinearLayout>

MainActivity.java

private static final int LOGIN = 0;
private static final int MAIN = 1;
private static final int FRAGMENT_COUNT = MAIN +1;
private Fragment[] fragments = new Fragment[FRAGMENT_COUNT]

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    FragmentManager fm = getSupportFragmentManager();
    fragments[LOGIN] = fm.findFragmentById(R.id.login_fragment);
    fragments[MAIN] = fm.findFragmentById(R.id.main_fragment);

    FragmentTransaction transaction = fm.beginTransaction();
    for (Fragment f : fragments) {
        if (f != null)
            transaction.hide(f);
        else
            Log.e(TAG, "???");
    }

    transaction.commit();
}

The thing is that when I call fm.findFragmentById(R.id.login_fragment); I get a null but when I call fm.findFragmentById(R.id.main_fragment); I get the fragment.

Błażej Michalik
  • 4,474
  • 40
  • 55
simperreault
  • 896
  • 1
  • 7
  • 17
  • Post the complete crash log and your fragment code – Libin Apr 29 '14 at 00:33
  • 1
    Thanks for your quick answer, I found the solution (was using support.v4 in one fragment and the normal type in the other one) I can't post the solution right now, because i don't have 10 reputations, but will answer myself tomorrow. I search a bit before and I found nothing related to that. – simperreault Apr 29 '14 at 01:14
  • I suspect that could be the issue. Any way your found it . Good – Libin Apr 29 '14 at 01:15

6 Answers6

102

The answer Kar0t is perfectly fine but this may help somebody. On my case I had a fragment inside of a fragment and I was getting the wrong FragmentManager. I just had to call:

getChildFragmentManager()

and then just find the Fragment as usual:

fm.findFragmentById(R.id.fragment)
Community
  • 1
  • 1
codeskraps
  • 1,461
  • 2
  • 12
  • 13
  • 7
    I was struggling here also. Thank you so much! – Francisco Romero Dec 13 '16 at 00:28
  • Working! When I use tag to add fragment in fragment, getChildFragmentManager() is worked and getFragmentManager() is not worked. And If I added fragment using getFragmentManager() promatically in parent fragment , getFragmentManager() is worked. Then If I add fragment in fragment promatically , I have to use getChildFragmentManager()? – inhogo Mar 21 '18 at 05:16
  • @inhogo For adding `Fragment` both works, but for finding `Fragment`, if you are inside `Fragmnet`, you have to use `getChildFragmentManager()`. – Sam Chen Mar 12 '21 at 16:03
37

just found out my mistake.

In my MainActivity.java i was importing android.support.v4.app.Fragment; and in my LoginFragment.java i was importing android.app.Fragment;. I changed it to the same thing and fm.findFragmentById(R.id.login_fragment) now return the right fragment.

simperreault
  • 896
  • 1
  • 7
  • 17
  • I wasted all day trying to find an answer to a similar problem, thanks – ppp Jul 23 '14 at 10:06
  • 2
    Thanks for the insight. In my case using getSupportFragmentManager() instead of getFragmentManager() solved the problem as my underlying fragment was from support package. – vir us Oct 12 '15 at 23:02
  • Holy heck ... waste of time too. Think Jetbrains is a bit overzealous about importing what it _thinks_ is right. I've seen this in C# with Rider before. – MikeMurko May 17 '19 at 20:02
7

Not really related to the specific question but related to receiving null on findFragmentById, if you call findFragmentById immediately after commit it will return null or the last fragment(before commit), the reason because commit do async request.

From docs:

Schedules a commit of this transaction. The commit does not happen immediately; it will be scheduled as work on the main thread to be done the next time that thread is ready.

If you need to findFragmentById immediately, for example change status bar text color after adding fragment, call executePendingTransactions() after commit()

getSupportFragmentManager().executePendingTransactions();
//call findFragmentById 
Pavel Poley
  • 5,307
  • 4
  • 35
  • 66
4

Kotlin

I also had problem because I was in a child fragment. I could use:

    supportFragmentManager.fragments.forEach {
        it.childFragmentManager.fragments.forEach { fragment ->
            if (fragment is HomeFragment) {
                //do something
            } 
        }

but one coworker optimized it with :

     if( findNavController(R.id.nav_host_fragment).currentDestination?.id == R.id.homeFragment) {
       // do something
   }
Community
  • 1
  • 1
Barbara K
  • 613
  • 6
  • 7
1

I encountered this problem because my project has two layout with the same file name. eg. In your case, I have two activity_main.xml in different modules.

So somehow it get compiled and when you run

fm.findFragmentById(R.id.login_fragment)

then it is looking for the fragment in the other activity_main.xml, which is null.

If this is the case, just check your file names of layouts, make sure they are unique.

Hope this help anyone with the same issue as mine. :)

ShengX
  • 41
  • 5
0

It is android life everyday something DEPRICATED, we are looking to samples and manual but they already not working)

My issue was in mix "import android.app.Fragment;" with modern "androidx.fragment.app.Fragment". Below sample for androidx

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

            Fragment myFrag = getSupportFragmentManager().findFragmentById(R.id.frgmContainer);
            if(myFrag==null)
                return;
            ((TextView) myFrag.getView().findViewById(R.id.textView))
                    .setText("Access to Fragment 2 from Activity"); 
Dmitry Ivanov
  • 508
  • 7
  • 9