Ajouter Imbriquée Fragment après Fragment Parent vue est déjà créé
Je suis en train de créer un Fragment qui a une méthode publique pour l'ajout de l'enfant des Fragments de lui-même.
J'ai de la lecture à travers potentiellement des questions similaires, mais n'ai rien trouvé jusqu'à présent. J'ai réduit le problème à une simple application de test indiqué ci-dessous.
Une fois fragA
a été ajouté à la page principale, j'ai appeler la méthode publique fragA.addFragB()
de l'obtenir pour ajouter une instance de FragmentClassB à lui-même, mais cela entraîne l'application de test de crash, en indiquant "l'Activité a été détruit" (voir le LogCat à la fin du post). Est-ce à dire fragA
a été détruit donc je ne peux pas ajouter fragB
, ou signifie-t-il fragB
a été détruit donc je ne peux pas l'ajouter à fragA
? Ou signifie-t-il quelque chose de complètement différent?
MainActivity.java
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragMan = getSupportFragmentManager();
//add Fragment A to the main linear layout
FragmentTransaction fragTrans = fragMan.beginTransaction();
FragmentClassA fragA = new FragmentClassA();
fragTrans.add(R.id.mainLinearLayout, fragA);
fragTrans.addToBackStack("A");
fragTrans.commit();
//get Fragment A to add a Fragment B to itself
fragA.addFragB();
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/mainLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
FragmentClassA.java
public class FragmentClassA extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_a, container, false);
}
public void addFragB() {
FragmentManager childFragMan = getChildFragmentManager();
FragmentTransaction childFragTrans = childFragMan.beginTransaction();
FragmentClassB fragB = new FragmentClassB();
childFragTrans.add(R.id.fragA_LinearLayout, fragB);
childFragTrans.addToBackStack("B");
childFragTrans.commit();
}
}
fragment_a.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragA_LinearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
</LinearLayout>
FragmentClassB.java
public class FragmentClassB extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_b, container, false);
}
}
fragment_b.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
LogCat
11-18 16:17:05.627: E/AndroidRuntime(14351): FATAL EXCEPTION: main
11-18 16:17:05.627: E/AndroidRuntime(14351): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.nestedfragmenttest/com.example.nestedfragmenttest.MainActivity}: java.lang.IllegalStateException: Activity has been destroyed
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.os.Handler.dispatchMessage(Handler.java:99)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.os.Looper.loop(Looper.java:137)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.main(ActivityThread.java:5103)
11-18 16:17:05.627: E/AndroidRuntime(14351): at java.lang.reflect.Method.invokeNative(Native Method)
11-18 16:17:05.627: E/AndroidRuntime(14351): at java.lang.reflect.Method.invoke(Method.java:525)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-18 16:17:05.627: E/AndroidRuntime(14351): at dalvik.system.NativeStart.main(Native Method)
11-18 16:17:05.627: E/AndroidRuntime(14351): Caused by: java.lang.IllegalStateException: Activity has been destroyed
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.example.nestedfragmenttest.FragmentClassA.addFragB(FragmentClassA.java:26)
11-18 16:17:05.627: E/AndroidRuntime(14351): at com.example.nestedfragmenttest.MainActivity.onCreate(MainActivity.java:25)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.Activity.performCreate(Activity.java:5133)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-18 16:17:05.627: E/AndroidRuntime(14351): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-18 16:17:05.627: E/AndroidRuntime(14351): ... 11 more
EDIT:
ianhanniballake la réponse de GrIsHu plus tard, la réponse qui s'étend sur le même point ont été utiles en soulignant la racine du problème. Cependant, cela soulève une autre question.
La finale intention est que FragmentClassA de faire partie d'une bibliothèque. Il sera utilisé dans plusieurs situations et le nombre de FragmentClassB instances varie, ou il peut même être nul. Donc j'ai besoin d'être en mesure de déclencher l'ajout de l'enfant fragments à toute instance de FragmentClassA de l'activité parent. J'ai juste eu un coup d'oeil à garder fragA
comme un niveau de classe de la variable dans MainActivity
et puis l'appel de fragA.AddFragB()
dans le MainActivity
's onActivityCreated()
méthode, mais il n'est pas disponible pour être substituée. Toutes les pensées?
OriginalL'auteur Sound Conception | 2013-11-18
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas charger directement le morceau que vous avez déclaré dans
FragA
. Les FragmentA sera chargé en premier, et puis après vous pouvez charger le FragmentB par l'appel de la méthodeaddFragB()
de votrefragA's
onCreateView()
méthode.Essayer comme ci-dessous:
Supprimer la ligne
fragA.addFragB();
de votre MainActivityEt essayez de charger le
FragmentB
deFragmentA
comme ci-dessous:Eh bien, la chose de laquelle vous souhaitez mettre en œuvre est un peu compliqué et n'est pas valide façon à mettre en œuvre. Pouvez-vous me dire dans quelle bibliothèque de votre
FragmentA
classe va résider ?Pour clarifier, FragmentA fera partie d'un Android à un Projet de Bibliothèque. Il fonctionne de manière similaire à une Palette d'outils tels que vous trouvez dans les éditeurs graphiques, traitement de texte etc. Le contenu de l'Outil de Palettes qui varient selon ce qui est logique pour le type de fichier ouvert dans l'application. Je pensais que le passage à la Imbriquée Fragments peuvent être tout à fait commode pour la réorganisation de ces Outil de Palettes en tant que de besoin. Mais à partir du son de celui-ci, je devrais probablement s'en tenir à mon ancienne méthode de construction de l'Outil de Palettes Personnalisé Composé Widgets plutôt que de l'Enfant Fragments. Est-ce que vous êtes en train de dire?
En fait, maintenant, je pense plus à ce sujet, mon test application ne permet pas de refléter la situation réelle. L'Outil de Palettes (FragmentA) sera créé, mais pas remplie lorsque l'application démarre. Ils ne seront pas remplie jusqu'à ce que l'utilisateur ouvre un fichier, FragmentA sera certainement existent déjà. Peut-être que je peux encore utiliser le sous-Fragment d'approche après tout?
Cette solution suppose que FragmentB est un enfant de FragmentA. Que faire si FragmentB était la soeur de FragmentA et vous avez voulu vous charger FragmentB APRÈS FragmentA a chargé? Je doute que vous pouvez utiliser getChildFragmentManger.
OriginalL'auteur GrIsHu
FragmentTransaction.commit
n'est pas une action immédiate, comme par la documentation donc votrefragA
n'est pas attaché à une Activité (donc pourquoi il renvoie à ce que l'activité est détruite) lorsque vous appelezfragA.addFragB()
.Vous devrait plutôt appeler
addFragB()
dansFragmentClassA.onCreate()
pour assurerfragA
est attaché à une activité et prêt à initialiser son propre état.OriginalL'auteur ianhanniballake
Avez-vous essayé d'ajouter ce point à l'enfant de fragments:
cela permettra d'éviter des problèmes lors de l'exécution de la commutation entre les différents fragments.
Disons que vous avez une activité avec un Fragment, qui à son tour aura deux enfants fragments:
fragA
etFragB
.Vous pouvez mettre en œuvre enfant fragments de quelque chose comme ceci:
activity_mymessages.xml
Laissez-moi savoir si cela fonctionne, si non je peux fournir le code de travail de mon GitHub.
OriginalL'auteur Oliver.Oakley