web-dev-qa-db-fra.com

findFragmentById renvoie null

Lorsque j'appelle findFragmentById () avec l'ID de mon fragment, il renvoie null. Permettez-moi de vous montrer le code.

L'activité_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>

Le 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();
}

Le fait est que lorsque j'appelle fm.findFragmentById(R.id.login_fragment); j'obtiens null mais quand j'appelle fm.findFragmentById(R.id.main_fragment); j'obtiens le fragment.

29
Kar0t

viens de découvrir mon erreur.

Dans mon MainActivity.Java, j'importais Android.support.v4.app.Fragment; Et dans mon LoginFragment.Java, j'importais Android.app.Fragment;. Je l'ai changé pour la même chose et fm.findFragmentById(R.id.login_fragment) retourne maintenant le bon fragment.

34
Kar0t

La réponse Kar0t est parfaitement correcte mais cela peut aider quelqu'un. Sur mon cas, j'avais un fragment à l'intérieur d'un fragment et j'obtenais le mauvais FragmentManager. Je devais juste appeler:

getChildFragmentManager()

puis il suffit de trouver le fragment comme d'habitude:

fm.findFragmentById(R.id.fragment)
83
codeskraps

Pas vraiment lié à la question spécifique mais lié à la réception de null sur findFragmentById, si vous appelez findFragmentById immédiatement après la validation, il renverra null ou le dernier fragment (avant la validation), la raison parce que commit fait une demande asynchrone.

Depuis les documents:

Planifie une validation de cette transaction. La validation ne se produit pas immédiatement; il sera planifié en tant que travail sur le thread principal à effectuer la prochaine fois que ce thread sera prêt.

Si vous devez findFragmentById immédiatement, par exemple changer la couleur du texte de la barre d'état après avoir ajouté un fragment, appelez executePendingTransactions() après commit()

getSupportFragmentManager().executePendingTransactions();
//call findFragmentById 
4
Pavel Poley

Kotlin

J'ai aussi eu un problème parce que j'étais dans un fragment d'enfant. Je pourrais utiliser:

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

mais un collègue l'a optimisé avec:

     if( findNavController(R.id.nav_Host_fragment).currentDestination?.id == R.id.homeFragment) {
       // do something
   }
0
Barbara K