Comment utiliser (ou "Pouvons-nous utiliser") getChildFragmentManager()
sur des programmes programmés (dynamiquement) ajoutés Fragment
s?
Voici mon exemple.
J'ai un MainActivity
, un OuterFrag
et un InnerFrag
. Je vais ajouter le OuterFrag
à MainActivity
dynamiquement par le FragmentManager
. Et aussi, j'ajouterai le InnerFrag
au OuterFrag
aussi dynamiquement par le FragmentManager
. Mais je veux ajouter InnerFrag
exactement comme un enfant du OuterFrag
, sans remplacer OuterFrag
et être le nouvel enfant du MainActivity
.
Je veux garder cette hiérarchie: MainActivity -> OuterFrag -> InnerFrag
. Ainsi, MainActivity peut toujours appeler OuterFrag.
Mais PAS changer de cette hiérarchie: MainActivity -> OuterFrag
À cette hiérarchie: MainActivity -> InnerFrag
Que MainActivity
perdra le OuterFrag
.
Voici mon exemple de code.
MainActivity.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().add(R.id.frameLayout, new OuterFrag()).commit();
getSupportFragmentManager().executePendingTransactions();
System.out.println("Before: "
+ getSupportFragmentManager().findFragmentById(R.id.frameLayout));
((OuterFrag) getSupportFragmentManager().findFragmentById(R.id.frameLayout))
.addInnerFrag();
System.out.println("After: "
+ getSupportFragmentManager().findFragmentById(R.id.frameLayout));
}
}
activity_main.xml
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/frameLayout"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent" >
</FrameLayout>
OuterFrag.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
public class OuterFrag extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.outer_frag, container, false);
}
public void addInnerFrag() {
getFragmentManager().beginTransaction().replace(this.getId(), new InnerFrag()).commit();
getFragmentManager().executePendingTransactions();
// getChildFragmentManager().beginTransaction().add(this.getId(), new InnerFrag()).commit();
// getChildFragmentManager().executePendingTransactions();
}
}
externe_frag.xml
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/textView1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="i am the OUTER frag" />
InnerFrag.Java
package com.example.frag;
import Android.os.Bundle;
import Android.support.v4.app.Fragment;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
public class InnerFrag extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.inner_frag, container, false);
}
}
inner_frag.xml
<TextView xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/textView2"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="i am the INNER frag" />
Actuellement, le code ci-dessus peut s'exécuter sans erreur. Mais cela change en fait InnerFrag
en tant que nouvel enfant de MainActivity
. Cela peut être vérifié par les deux instructions System Print Out que l'objet Before: Object et After: Object est modifié. Dans OuterFrag.Java
, Si les instructions getChildFragmentManager()
sont exécutées au lieu des instructions getFragmentManager()
, nous obtiendrons l'erreur d'exécution suivante:
12-07 02:29:38.406: E/AndroidRuntime(12051): Java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.frag/com.example.frag.MainActivity}: Java.lang.IllegalArgumentException: No view found for id 0x7f070000 (com.example.frag:id/frameLayout) for fragment InnerFrag{46e32748 #0 id=0x7f070000}
L'utilisation de getChildFragmentManager()
est théoriquement correcte. Il peut être utilisé dans un fragment non programmé ajouté (ce qui signifie changer le activity_main.xml
De <FrameLayout>
En <fragment>
, Ajouter l'attribut Android:name="com.example.frag.OuterFrag"
Et supprimer le premier getSupportFragmentManager()
instruction dans MainActivity.Java
). Et il garde la bonne hiérarchie: MainActivity -> OuterFrag -> InnerFrag
. Mais les mots du fragment original (outer_frag.xml
) Ne peuvent jamais être enlevés.
En conclusion, je veux toujours référencer OuterFrag
dans MainActivity
. Et je veux que OuterFrag
agisse comme un espace réservé pour charger différents InnerFrag
s. En bref, je veux appeler getChildFragmentManager()
dans OuterFrag
, quand il est ajouté par programme (dynamiquement).
En conclusion, je veux toujours faire référence à OuterFrag dans MainActivity. Et je veux qu'OuterFrag agisse comme un espace réservé pour charger différents InnerFrags. En bref, je veux appeler getChildFragmentManager () dans OuterFrag, lorsqu'il est ajouté par programme (dynamiquement).
Si vous le souhaitez, faites en sorte que votre OuterFrag
ait une disposition de conteneur comme contenu et ajoutez ce que InnerFrag
à ce conteneur. Le fichier de mise en page pour le OuterFrag
sera:
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/fragContainer"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
/>
Bien sûr, vous pouvez avoir d'autres vues dans la mise en page pour le OuterFrag
si vous le souhaitez. Votre méthode addInnerFrag
sera alors:
public void addInnerFrag() {
getChildFragmentManager().beginTransaction().add(R.id.fragContainer, new InnerFrag()).commit();
getChildFragmentManager().executePendingTransactions();
}
Le code pour ajouter le OuterFrag
à l'activité principale reste valide.