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.
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.
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)
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
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
}