1

Mon application a une activité A et deux fragments F1 et F2.Communication entre deux fragments avec interface

En cliquant sur le bouton F1, F1 est remplacé par F2. Je veux transférer des données dans F1 à F2. Pour cela, je mis en œuvre l'interface en F1 et remplacer la méthode de A.

Mais lors de l'envoi des données de A à F2, ma référence (sFragment dans le code A) au F2 reste nulle, en raison de laquelle les données ne sont pas envoyées à F2. Je reçois référence à la F2 en utilisant TAG fourni en remplaçant F1 par F2.

Cela a-t-il quelque chose à voir avec le cycle de vie, comme lorsque j'essaie d'obtenir une référence à la F2 qu'elle n'a pas encore créée?

F1

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 

    View v = inflater.inflate(R.layout.form_fragment1,container,false); 
    nextB = (Button) v.findViewById(R.id.f1Next); 
    nextB.setOnClickListener(this); 
    return v; 
} 

@Override 
public void onClick(View view) { 
    switch (view.getId()){ 

     case R.id.f1Next: 
      SFragment fragment = new SFragment(); 
      FragmentManager mManager = getFragmentManager(); 
      FragmentTransaction mTransaction = mManager.beginTransaction(); 
      mTransaction.replace(R.id.fragment_container,fragment,"SecondF"); // SecondF 
      mTransaction.addToBackStack(null); // this is required to move to the previous fragment 
      mTransaction.commit(); 
      commListener.PlaceName(data1,data2); //passing value to activity 
      break; 

    } 

} 
interface CommBridge{ 

    void PlaceName(String data1,String data2); 
} 

@Override 
public void onAttach(Context context){ 
    super.onAttach(context); 
    if (context instanceof CommBridge){ 
     commListener= (CommBridge) context; 
    } 
} 

}

A

@Override 
public void PlaceName(String data1, String data2) { 
    SFragment sFragment=(SFragment) getFragmentManager().findFragmentByTag("SecondF"); 
    if (sFragment != null && sFragment.isInLayout()){ 
     Log.d("STATE","1"); 
     sFragment.setPlace(data1,data2); 
    }else{ 
     Log.d("STATE","2"); // this is always the case 
    } 

F2

public class SFragment extends Fragment { 
String Place2,Place1; 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ 
    View v = inflater.inflate(R.layout.form_fragment2,container,false); 
    return v; 
} 

void setPlace(String data1, String data2){ 
    place1 = data1; 
    place2 = data2; 

} 
} 
+1

vous devez utiliser 'Bundle' pour envoyer des données d'un fragment t o un autre fragment. – Shailesh

Répondre

0

je recommande de mettre le code pour remplacer le fragment dans votre activité et de mettre les valeurs qui doivent être transmises à SFragment() dans ses arguments directement:

SFragment newFragment = new SFragment(); 
Bundle args = new Bundle(); 
args.putString("place1", data1); 
args.putString("place2", data1); 
newFragment.setArguments(args); 

Vous pouvez les obtenir dans SFragment#onCreateView()

String place1 = getArguments().getString("place1"); 

Regardez également ici: https://developer.android.com/training/basics/fragments/communicating.html

+0

Cela a résolu mon problème Marius. Mais pourquoi m'as-tu recommandé de mettre le code de remplacement dans Activité? Aussi n'est-ce pas le cas de la communication directe entre les fragments qui devrait être évitée? –

+0

L'activité doit être en contrôle et gérer ses fragments. Le fragment spécifique ne devrait littéralement pas savoir qu'il y a un autre fragment. Ensuite, lorsque vous voulez remplacer un fragment, vous n'avez qu'à toucher l'activité de contrôle et ne pas chercher dans chaque fragment. – noongiya95

+0

Dans ma compréhension, la communication directe est seulement si vous essayez d'appeler des méthodes d'un fragment d'un autre fragment. Passer des arguments sur l'activité de contrôle est le moyen commun de communiquer. – noongiya95

2

Laissez l'activité s'occuper de l'événement onClick du fragment. Voir l'exemple ci-dessous.

Activité:

import android.os.Bundle; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 

public class MainActivity extends AppCompatActivity implements Fragment1.CommBridge { 


    private Fragment1 fragment1 = new Fragment1(); 
    private Fragment2 fragment2 = new Fragment2(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 

     getSupportFragmentManager() 
       .beginTransaction() 
       .replace(R.id.content, fragment1) 
       .commit(); 


    } 

    @Override 
    public void onButtonClicked(String data1, String data2) { 
     fragment2.setData(data1, data2); 
     getSupportFragmentManager() 
       .beginTransaction() 
       .replace(R.id.content, fragment2) 
       .commit(); 
    } 
} 

Fragment1:

import android.content.Context; 
import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.Button; 

public class Fragment1 extends Fragment { 

    interface CommBridge { 
     void onButtonClicked(String data1, String data2); 
    } 

    private CommBridge handler; 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     if (context instanceof CommBridge) { 
      handler = (CommBridge) context; 
     } 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment1, container, false); 

     Button button = (Button) view.findViewById(R.id.button); 
     button.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       handler.onButtonClicked("Data1", "Data2"); 
      } 
     }); 

     return view; 
    } 
} 

Fragment2

import android.os.Bundle; 
import android.support.annotation.Nullable; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.TextView; 

public class Fragment2 extends Fragment { 

    private String data1; 
    private String data2; 

    public void setData(String data1, String data2) { 
     this.data1 = data1; 
     this.data2 = data2; 
    } 

    @Nullable 
    @Override 
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment2, container, false); 

     TextView textView = (TextView) view.findViewById(R.id.textView); 
     textView.setText(data1 + "\n" + data2); 

     return view; 
    } 
}