2016-02-09 5 views
3

Je rencontre actuellement des problèmes avec les fragments d'imbrication, j'ai créé un SlidingTabLayout avec deux onglets, chaque onglet avec son Fragment correspondant, Dans un onglet j'ai ajouté 5 fragments enfants au fragment parent retourné par le FragmentPagerAdapter, mais je ne parviens pas à la communication entre le fragment parent et des enfants fragment,Fragments imbriqués Communication

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

      FragmentTransaction childManager=getChildFragmentManager().beginTransaction(); 
      childManager.add(R.id.linear08,new YearFragment08(),"year08"); 
      childManager.commit(); 
      YearFragment08 year08=(YearFragment08)getChildFragmentManager().findFragmentByTag("year08"); 
      year08.setinfo("This is fantastic"); 


} 

`

public class YearFragment08 extends Fragment { 
TextView yearInfo; 
@Nullable 
@Override 
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
    View v=inflater.inflate(R.layout.year_frag08,container,false); 
    yearInfo=(TextView)v.findViewById(R.id.txt_yearInfo_08); 
    return v; 
} 
public void setinfo(String data){ 
    yearInfo.setText(data); 
} 

et voici le résultat.

02-09 21:45:48.078 2177-2177/com.compassasu.compass E/AndroidRuntime﹕ FATAL EXCEPTION: main 
Process: com.compassasu.compass, PID: 2177 
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.compassasu.compass.Fragments.YearFragment08.setinfo(java.lang.String)' on a null object reference 
     at com.compassasu.compass.Fragments.HistoryFragment.onActivityCreated(HistoryFragment.java:33) 
     at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1970) 
     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1051) 
     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207) 
     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738) 
     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1572) 
     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:545) 
     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1106) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:952) 
     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1474) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
     at android.support.v7.internal.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:124) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5951) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
     at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643) 
     at android.view.View.measure(View.java:18788) 
     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2100) 
     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1216) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1452) 
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107) 
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
     at android.view.Choreographer.doFrame(Choreographer.java:606) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:148) 
     at android.app.ActivityThread.main(ActivityThread.java:5417) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

Tout ce que je veux savoir, c'est comment un fragment enfant reçoit des données du fragment parent.

Répondre

1

Le problème est que vous essayez de trouver le fragment par sa balise avant qu'il ait été réellement ajouté. Notez le documentation pour FragmentTransaction.commit():

Planifie une validation de cette transaction. Le commit ne se produit pas immédiatement ; il sera planifié que le travail sur le thread principal soit fait la prochaine fois que le thread est prêt.

Comme vous pouvez le voir le fragment n'est pas immédiatement ajouté c'est pourquoi null est retourné lorsque vous essayez d'obtenir le Fragment.

Pour résoudre ce problème, vous pouvez utiliser FragmentManager.executePendingTransactions() après validation de la transaction pour ajouter le fragment immédiatement:

getChildFragmentManager().beginTransaction() 
     .add(R.id.linear08,new YearFragment08(),"year08") 
     .commit(); 

getChildFragmentManager().executePendingTransactions(); 
YearFragment08 year08=(YearFragment08)getChildFragmentManager().findFragmentByTag("year08"); 
year08.setinfo("This is fantastic"); 

Notez également qu'une meilleure façon de le faire serait de créer le premier fragment YearFragment08 et l'utilisation Fragment arguments pour transmettre les informations que vous souhaitez afficher dans le Fragment. Ensuite, vous n'avez pas besoin d'utiliser la solution de contournement ci-dessus car vous n'aurez pas besoin d'appeler yearInfo.setText("Hi") lorsque le Fragment est créé. Vous pouvez trouver un exemple de création d'un Fragment avec les arguments here.

Mise à jour

Comme il est indiqué dans les longs commentaires, bien que la première approche permet getChildFragmentManager().findFragmentByTag("year08") de retourner le fragment est toujours pas une bonne idée d'appeler des méthodes sur le Fragment que l'accès à ses vues jusqu'à ce que onViewStateRestored(...) ou après a été appelé. Cela est dû au fait que lorsque vous utilisez le FragmentManager pour ajouter le fragment parent, la méthode onCreateView du fragment enfant ne sera pas appelée immédiatement après avoir appelé executePendingTransactions() pour que les vues référencées du fragment enfant soient null. Si le parent Fragment est utilisé directement dans la mise en page, cela ne pose aucun problème car onCreateView du fragment enfant est appelé dans le cadre de executePendingTransactions() et ses vues ne seront pas nulles. La meilleure chose à faire dans ce cas serait d'utiliser l'autre approche mentionnée qui utilise les arguments Fragment si vous devez définir des valeurs initiales pour les vues dans les fragments.

+0

02-09 22:30:07.148 7381-7381/com.compassasu.compass E/AndroidRuntime: FATAL EXCEPTION: principal Processus: com.compassasu.compass, PID: 7381 java.lang.NullPointerException: Tentative d'invocation de la méthode virtuelle 'void android.widget.TextView. setText (java.lang.CharSequence) » sur un objet null référence à com.compassasu.compass.Fragments.YearFragment08.setinfo (YearFragment08.java:27) ne fonctionne toujours pas, malheureusement –

+0

en fait, il a fait le travail que vous maintenant fait dans la méthode 'setText' de votre' Fragment'. Les nouveaux problèmes sont l'affichage du texte 'yearInfo' est' null' dans votre méthode 'setInfo'. Êtes-vous sûr qu'il est assigné dans la méthode 'onCreateView' de' YearFragment08'? Vérifiez le fichier 'year_frag08.xml' pour un' TextView' avec 'id = txt_yearInfo_08'. –

+0