0


J'ai récemment développé une petite application Android, mais j'ai dû faire face à un problème que je n'arrive pas à résoudre.Attribuer le bon fragment android à tour de rôle

Depuis que je suis sur un BottomNavigationView je dois initialiser mon fragment d'accueil comme celui-ci:

@Override 
protected void onStart(){ 
    super.onStart(); 
    FragmentTransaction f = fm.beginTransaction(); 
    f.replace(R.id.content, homeFragment).commit(); 
} 

le remplacement se produit sur cette FrameLayout:

<FrameLayout 
    android:id="@+id/content" 
    android:layout_width="0dp" 
    android:layout_height="0dp" 
    android:visibility="visible" 
    app:layout_constraintBottom_toTopOf="@+id/navigation" 
    app:layout_constraintEnd_toEndOf="parent" 
    app:layout_constraintHorizontal_bias="0.5" 
    app:layout_constraintStart_toStartOf="parent" 
    app:layout_constraintTop_toTopOf="parent" 
    app:layout_constraintVertical_bias="1.0" /> 

Pourtant, cela soulève un petit bug: si Je fais pivoter l'appareil, le fragment est remis à mon homeFragment, quel que soit le courant.
Puisque je ne peux pas appeler directement mon

public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
// 
} 

J'ai quelques retournements: tryed

  • J'ai tryed en utilisant un booléen isFragmentInitialized
  • J'ai tryed décentralisant la fonction onNavigation dans un externe fonction setFragment privée qui a vérifié l'élément de menu sélectionné et appliqué le fragment correspondant
  • J'ai essayé de démarrer directement avec homeFragment plutôt qu'avec la vue linéaire que j'utilise

Mais theese solutions apporte pas de chance:
le dernier se bloque après avoir allumé l'écran et sélectionnez la maison
les autres sont le résultat simplement dans la même situation avec mon initialisation standard.

Répondre

1

Probablement la chose la plus simple de le faire entraînera votre code à exécuter que la première fois que l'utilisateur accède à votre Activity est de déplacer votre code onStart()-onCreate() et l'envelopper dans une déclaration if qui vérifie si savedInstanceState est nulle (ce qui ne sera vrai que la première fois que l'activité démarre).

@Override 
protected void onCreate(Bundle savedInstanceState){ 
    super.onCreate(); 
    // the rest of your onCreate() etc... 

    if (savedInstanceState == null){ 
     FragmentTransaction f = fm.beginTransaction(); 
     f.replace(R.id.content, homeFragment).commit(); 
    } 
} 

Vous pouvez utiliser cette technique pour tout ce que vous voulez exécuter uniquement la première fois votre activité démarre, et pas seulement avec FragmentTransaction s. Bien que les fragments sont un cas d'utilisation très commun pour cette astuce.

+0

Cela fonctionne beaucoup! Merci pour la réponse rapide et utile! – Tails128

0

Une façon de procéder consiste à créer une variable pour stocker une étiquette de fragment, dans le cas de commutateur qui gère votre navigation en bas, vous pouvez enregistrer la variable appropriée dans cette variable. Ensuite, implémentez la fonction onSaveInstanceState et écrivez cette balise à votre revendeur. Enfin, écoutez un état d'instance enregistré dans onCreate et lancez le fragment approprié. Quelque chose comme ceci:

String fragmentTag; 
String FRAGMENT-TAG-KEY = "fragment-tag"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // recovering the instance state 
    if (savedInstanceState != null) { 
     String fragmentTag = savedInstanceState.getString("FRAGMENT-TAG-KEY"); 
     switch (fragmentTag){ 
      case "FragmentA": { 
       //launch this fragment. 
       break; 
      } 
      case "FragmentB": { 
       //launch this fragment. 
       break; 
      } 
     } 
    } 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    outState.putString(FRAGMENT-TAG-KEY, fragmentTag); 
    super.onSaveInstanceState(outState); 
} 


bottomNavigationView.setOnNavigationItemSelectedListener(
    new BottomNavigationView.OnNavigationItemSelectedListener() { 
     @Override 
     public boolean onNavigationItemSelected(@NonNull MenuItem item) { 
      switch (item.getItemId()) { 
       case R.id.action_home: { 
        fragmentTag = "FragmentA"; 
       } 

       case R.id.action_fragmentb: { 
        fragmentTag = "FragmentA"; 
       } 
      } 
      return true; 
     } 
    }); 

Si c'est le cas que ce fragment particulier a besoin pour stocker des données, vous pouvez stocker localement et le recharger. Sinon, vous devrez peut-être renvoyer les données à l'activité, puis les transférer dans votre fragment. Il se peut que vous puissiez stocker l'instance de votre fragment et implémenter l'entité dans le fragment, puis dans le fragment onActivityCreated, vous pouvez restaurer votre état d'instance. Je ne suis pas sûr de savoir à quoi ressemble le reste de votre code, donc je ne peux que spéculer sur la manière dont vous pouvez stocker les données de votre fragment s'il en a.